Как работают значения интерфейса nil в Golang - PullRequest
1 голос
/ 18 июня 2020

У меня есть следующий код для проверки, когда значение интерфейса golang ложно.

package main

import (
    "fmt"
)

func Foo(x interface{}) {
    fmt.Println("33, x == nil = ", x == nil)
}
func main() {
    var x *int = nil
    fmt.Println("11, x == nil = ", x == nil)

    var a interface{}
    fmt.Println(22, &a, &a == nil, a == nil) // 0xc0000935c0 false true
    Foo(x)
}

Результат:

11, x == nil =  true
22 0xc00010a040 false true
33, x == nil =  false

Я не понимаю вывод. Особенно я не понимаю, почему &a не равен нулю, потому что a не инициализирован. Кто-нибудь может помочь мне объяснить результат? Спасибо.

1 Ответ

1 голос
/ 18 июня 2020

В go вам нужно помнить два момента, когда дело доходит до значений интерфейса nil:

  1. Значение интерфейса nil, которое вообще не содержит значения, не то же самое, что значение интерфейса, содержащее значение, которое оказывается равным нулю.
  2. Интерфейс, содержащий нулевое значение, не равен нулю

Пример, объясняющий 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...