Найти в Дзене
2023 подписчика

🖥 Анатомия интерфейсов в Go


В процессе знакомства с Go я нашел в документации пример:

func returnsError() error {

var p *MyError = nil

if bad() {

p = ErrBad

}

return p // Will always return a non-nil error.

}

После его просмотра меня заинтересовало, почему returnsError всегда будет возвращать не non-nil error?

Переменные в Go всегда инициализируются значением. Это относится и к интерфейсам. Стоит отметить, что интерфейсы реализованы в виде двух элементов: тип(T) и значение(V). Это достаточно поверхностное определение, которое чуть дальше мы разберем. Значение интерфейса будет nilтолько в том случае, если Vи T оба будут nil.

Есть интересный момент, а именно случай, когда V=nil, а T!=nil. В таком случае никакие проверки интерфейса на nil нам не помогут. А ведь именно этот сценарий и происходит в returnsError.

Мне стало интересно, как именно эти проверки проходят в Go.

type Word struct {

name string

priority uint

}

type Foo interface {

foo()

}

func (w *Word) foo() {

fmt.Println("call foo()")

}

func (w *Word) noFoo() {

fmt.Println("call noFoo()")

}

func call(f Foo) {

if f != nil {

f.foo()

} else {

fmt.Println("f null")

}

}

func main() {

var f1 *Word

call(f1)

}


🖥 Анатомия интерфейсов в Go В процессе знакомства с Go я нашел в документации пример: func returnsError() error { var p *MyError = nil if bad() { p = ErrBad } return p // Will always return a non-nil
Около минуты