面试题答案
一键面试命名类型定义结构体
package main
import "fmt"
// 定义命名类型
type Point struct {
X int
Y int
}
func main() {
p := Point{X: 10, Y: 20}
fmt.Println(p)
}
未命名类型定义结构体
package main
import "fmt"
func main() {
p := struct {
X int
Y int
}{X: 10, Y: 20}
fmt.Println(p)
}
使用场景和特性区别
- 使用场景:
- 命名类型:适用于需要在多个地方复用相同结构体定义的场景。比如在一个图形绘制库中,
Point
结构体可能会在绘制线条、图形等多处使用,命名类型使得代码更具可读性和可维护性。 - 未命名类型:适合在只需要使用一次结构体实例的场景,比如在某个函数内部,临时构造一个结构体来存储一些局部数据,用完即弃,不需要为其单独命名。
- 命名类型:适用于需要在多个地方复用相同结构体定义的场景。比如在一个图形绘制库中,
- 特性区别:
- 命名类型:有自己独立的类型名称,可以在包的其他地方使用该名称来声明变量、定义函数参数和返回值等。不同包中如果要使用,还可以通过包名进行访问(前提是结构体字段首字母大写,即导出)。
- 未命名类型:没有独立类型名称,每个未命名结构体类型都是唯一的,即使结构体字段完全相同。不同地方定义的相同结构的未命名结构体类型不能相互赋值。例如:
package main
import "fmt"
func main() {
s1 := struct {
A int
}{A: 1}
s2 := struct {
A int
}{A: 2}
// 以下赋值会报错,因为s1和s2虽然结构相同,但属于不同的未命名类型
// s1 = s2
}
而命名类型只要是同一个命名类型,就可以相互赋值:
package main
import "fmt"
type S struct {
A int
}
func main() {
s1 := S{A: 1}
s2 := S{A: 2}
s1 = s2
fmt.Println(s1)
}