Как определить, является ли указатель структуры нулевым в golang? - PullRequest
0 голосов
/ 29 апреля 2019

Как показывает следующий код: n := localplugin.NewPluginNet(), тип n равен localnet.Net, который является интерфейсом, реализованным указателем структуры *localnet.DomainSocket.Функция func NewPluginNet() localnet.Net возвращает нулевой указатель на n.

var n localnet.Net    
n = localplugin.NewPluginNet()
fmt.Println("----> ", n)
if n == nil {
    fmt.Println("n is nil")
}else{
    fmt.Println("n is not nil : ",  n)
}
fmt.Println(reflect.TypeOf(n), reflect.TypeOf(nil), n)

Ниже приведен вывод приведенного выше кода.

---->  <nil>
n is not nil :  <nil>
*localnet.DomainSocket <nil> <nil>

Почему n не равно nil?

==========================================

var n1 *localnet.DomainSocket
n1 = nil
fmt.Println(">> ", n1)
if n1 == nil {
    fmt.Println(">>n1 is nil")
}else{
    fmt.Println(">>n1 is not nil : ",  n)
}
fmt.Println(reflect.TypeOf(n1), reflect.TypeOf(nil), n1)

Однако,это правильно для этого случая:

>>  <nil>
>>n1 is nil
*localnet.DomainSocket <nil> <nil>

1 Ответ

5 голосов
/ 29 апреля 2019

Почему не n nil?Тип n - это тип интерфейса (localnet.Net), который является оберткой для пары (type; value).Значение интерфейса может отличаться от nil, даже если оно содержит значение nil.См. Скрытие nil-значений, понимание того, почему golang терпит неудачу, здесь

Чтобы ответить на вопрос в заголовке: вы можете использовать отражение, чтобы определить, содержит ли значение интерфейса не-1012 * значение nil(например, nil указатель):

reflect.ValueOf(someValue).IsNil()

Пример:

type reader struct{}

func (*reader) Read(p []byte) (int, error) { return 0, nil }

func main() {
    var r io.Reader = (*reader)(nil)

    fmt.Println(r, r == nil)
    fmt.Println(reflect.ValueOf(r).IsNil())
}

Вывод (попробуйте на Go Playground ):

<nil> false
true
...