func(d *Dog) Speak() string { if d == nil { return"<silence>"// 即使接收者是nil指针,方法也能被调用 } return"Woof! My name is " + d.Name }
funcmain() { var s Speaker // s 是一个接口变量, 目前 (type=nil, value=nil) fmt.Printf("Initial: s=(%T, %v), is nil? %v\n", s, s, s == nil) // 输出: Initial: s=(<nil>, <nil>), is nil? true
var d *Dog // d 是一个具体的指针类型 *Dog,值为 nil fmt.Printf("d is nil? %v\n", d == nil) // 输出: d is nil? true
s = d // 将一个具体的 nil 指针赋值给接口变量 // 此时 s 的内部状态: (type=*main.Dog, value=nil) // 注意:类型信息 *main.Dog 被记录了!
fmt.Printf("After assignment: s=(%T, %v), is nil? %v\n", s, s, s == nil) // 输出: After assignment: s=(*main.Dog, <nil>), is nil? false
if s != nil { fmt.Println("s is not nil, calling Speak():", s.Speak()) // 输出: s is not nil, calling Speak(): <silence> } }
func(d *Dog) Speak() string { if d == nil { return"<silence>" } return"Woof! My name is " + d.Name }
funcmain() { var d *Dog // d is nil var s Speaker = d // s is (*main.Dog, nil)
if s == nil { fmt.Println("s is truly nil (type and value are nil)") } else { // s 不为 nil,需要进一步检查内部 value dog, ok := s.(*Dog) // 类型断言 if ok && dog == nil { fmt.Println("s is not nil, but its underlying value (*Dog) is nil") } elseif ok { fmt.Println("s holds a non-nil *Dog:", dog.Name) } else { fmt.Println("s holds a different type:", s) } }
// 示例:持有非nil值的接口 goodDog := &Dog{Name: "Buddy"} s = goodDog // s is (*main.Dog, &{Buddy}) if s != nil { dog, ok := s.(*Dog) if ok && dog == nil { fmt.Println("s is not nil, but its underlying value (*Dog) is nil") } elseif ok { fmt.Println("s holds a non-nil *Dog:", dog.Name) // 输出: s holds a non-nil *Dog: Buddy } } }
funcmain() { var d *Dog // d is nil var s Speaker = d // s is (*main.Dog, nil)
if s == nil { fmt.Println("Interface is nil") } else { // 使用反射检查内部值 val := reflect.ValueOf(s) // IsNil() 只能用于 chan, func, interface, map, pointer, slice if val.Kind() == reflect.Ptr && val.IsNil() { fmt.Println("Interface is not nil, but underlying pointer value is nil") } else { fmt.Println("Interface is not nil and underlying value is not nil (or not a pointer)") } } }
// Bad practice: 可能返回一个非nil接口,其内部值为nil funcFindSpeakerBad() Speaker { var d *Dog = nil// 假设找不到 Dog // ... some logic ... return d // 返回 (*main.Dog, nil) }
// Good practice: 如果没有有效值,直接返回nil接口 funcFindSpeakerGood() Speaker { var d *Dog = nil// 假设找不到 Dog // ... some logic ... if d == nil { returnnil// 直接返回 (nil, nil) 接口 } return d }
funcmain() { sBad := FindSpeakerBad() if sBad != nil { fmt.Println("FindSpeakerBad returned non-nil interface") // 会执行 } else { fmt.Println("FindSpeakerBad returned nil interface") }
sGood := FindSpeakerGood() if sGood != nil { fmt.Println("FindSpeakerGood returned non-nil interface") } else { fmt.Println("FindSpeakerGood returned nil interface") // 会执行 } }