Skip to content
On this page

结构体与接口

结构体字面量

go
type User struct {
    Name string
    Age  int
}

u := User{Name: "a", Age: 1}
v := User{"b", 2} // 须按字段声明顺序且不能跳过前面字段混用两种风格

嵌入(匿名字段)将字段与方法提升到外层:

go
type Inner struct{ X int }
type Outer struct {
    Inner // 嵌入,不是字段名 Inner
}
var o Outer
o.X = 1 // 提升到 Outer

嵌入指针时,nil 嵌入指针上访问提升字段会 panic。

导出规则

标识符首字母大写:包外可见;小写:包内私有。结构体字段、接口方法名均适用。

接口定义

接口是方法签名的集合。某类型 T 若拥有接口 I 所需的全部方法(且签名一致),则 T 满足 I无需显式 implements

空接口 interface{} / any 可被任意具体类型赋值(再取出时常需类型断言)。

接口值的表示

运行时接口值大致为 (动态类型, 动态值)。动态值为 nil 但动态类型非 nil 时,== nilfalse(常见陷阱):

go
var p *int = nil
var i any = p
// i == nil 为 false,因为接口内动态类型为 *int

类型断言

go
v, ok := i.(ConcreteType) // ok 为 false 时不 panic
v := i.(ConcreteType)    // 失败则 panic

switch i.(type) / switch t := i.(type) 做类型分支。

接口设计建议

  • 接口越小越好(如 io.Reader 单方法),便于测试与组合。
  • 在消费者侧定义小接口,而非在生产大包类型处声明巨大接口。
  • 需要可空行为时,用具体指针类型或显式 Optional 模式,勿依赖「nil 接口值」与「非 nil 接口装 nil 指针」混淆。

comparable 与接口

用作 map 键、== 的类型须可比较。接口动态值比较失败或不可比较类型会 panic

技术文库