суббота, 16 мая 2020 г.

Неверный адрес памяти или разыменование нулевого указателя в Golang

Почему эта программа паникует?

type Point struct {
    X, Y float64
}

func (p *Point) Abs() float64 {
    return math.Sqrt(p.X*p.X + p.Y*p.Y)
}

func main() {
    var p *Point
    fmt.Println(p.Abs())
}

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0xffffffff addr=0x0 pc=0xd2c5a]

goroutine 1 [running]:
main.(*Point).Abs(...)
 ../main.go:6
main.main()
 ../main.go:11 +0x1a

Ответ

Неинициализированный указатель p в main функции равен nil, и вы не можете следовать за нулевым указателем.

Если x равен nil, попытка выполнить *x вызовет панику во время выполнения. Спецификация языка программирования Go: адресные операторы.

Вам необходимо создать Point. С помощью new:

func main() {
    var p *Point = new(Point)
    fmt.Println(p.Abs())
}

Либо с помощи литерала с оператором ссылки:

func main() {
    var p *Point = &Point{}
    fmt.Println(p.Abs())
}

Поскольку методы с получателями указателей принимают либо значение, либо указатель, вы также можете вообще пропустить указатель:

func main() {
    var p Point // имеет нулевое значение Point{X:0, Y:0}
    fmt.Println(p.Abs())
}


Читайте также:


Комментариев нет:

Отправить комментарий