В go вам нужно помнить два момента, когда дело доходит до значений интерфейса nil:
- Значение интерфейса nil, которое вообще не содержит значения, не то же самое, что значение интерфейса, содержащее значение, которое оказывается равным нулю.
- Интерфейс, содержащий нулевое значение, не равен нулю
Пример, объясняющий 1 и 2:
package main
import "fmt"
func main() {
var i1 interface{}
fmt.Println("a == nil: ", i1 == nil)
var i2 interface{}
var p *int = nil
i2 = p
fmt.Println("b == nil: ", i2 == nil)
}
Вывод :
a == nil: true
b == nil: false
Как это работает за кулисами :
По сути, интерфейс в go состоит из двух вещей : а dynamic type
и dynamic value
. Когда вы присваиваете какое-либо значение nil * int интерфейсу, теперь его dynamic type
равно *int
, а dynamic value
равно nil, и поэтому интерфейс теперь не равен nil, и любое сравнение с nil приведет к ложному
Интерфейс равен нулю, только если оба его dynamic type
и dynamic value
равны нулю.
В вашем случае :
Вам нужно извлечь Dynami c значение интерфейса x, прежде чем сравнивать его с nil.
См. Следующий код:
package main
import (
"fmt"
)
func Foo(x interface{}) {
fmt.Println("22, x == nil = ", (x).(*int) == nil)//22, x == nil = true
}
func main() {
var x *int = nil
fmt.Println("11, x == nil = ", x == nil)// 11, x == nil = true
Foo(x)
}
Выход :
11, x == nil = true
22, x == nil = true