Pull to refresh

Comments 7

Эм, ожидал что последним абзацем будет листинг кода с проверкой при которой результатом выполнения будет fmt.Println("f null")

Держите:

package main

import "fmt"

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 != (*Word)(nil) {
		f.foo()
	} else {
		fmt.Println("f null")
	}
}

func main() {
	var f1 *Word
	call(f1)
}

Такой себе пример. А если у вас два типа реализующих интерфейс и в call передали указатель другой?

А код изначально не корректен. В функции call вообще не должно быть проверки на nil.
Проверку на nil скорее стоит поставить внутри метода foo, например чтоб вернуть zero value, как вариант, если метод что-то должен вернуть. Либо ошибку, и вот её уже стоит проверять в функции call.

Правильно ли я понял, что вы предлагаете внутри метода foo сделать проверку if w == nil?

Порекомендуйте, пожалуйста, какие-нибудь материалы на тему best-practices по избеганию null pointer dereference. Не так давно пишу на го и постоянно сталкиваюсь с этой бедой. Стараюсь поменьше использовать указатели, но все равно...

Вряд ли есть много структурированой информации на эту тему. Думаю, если функция возвращает результат+error, всегда нужно проверять error, и, если error != nil, не использовать результат. И свой код писать так же, если возвращаете результат и пустой error, результат должен быть не nil. Также всегда стоит быть уверенным, что была выделена память под slice или map прежде чем писать туда данные, так как slice и map это всегда неявный указатель. Если не уверены, лучше сделать проверку на nil и вызвать make.

Sign up to leave a comment.

Articles