Avatar ·

Что такое null/nil в Go и как с ним работать?

Всем привет! Начал изучать Go и столкнулся с концепцией nil. В других языках (например, Java или JavaScript) есть null, который часто вызывает ошибки (NullPointerException). В Go, как я понял, используется nil, но поведение отличается.

Вот что я пробовал:

package main

import "fmt"

func main() {
    var p *int
    fmt.Println(p) // выводит nil
    // fmt.Println(*p) // panic: runtime error: invalid memory address or nil pointer dereference
    
    var s []int
    fmt.Println(s == nil) // true
    fmt.Println(len(s))   // 0
    // s[0] = 1 // panic
    
    var m map[string]int
    fmt.Println(m == nil) // true
    // m["key"] = 1 // panic
}

Вопросы:

  1. Почему nil в Go не приводит к автоматическому созданию пустых структур (в отличие от null в некоторых ЯП)?
  2. Как правильно проверять на nil перед использованием указателей, срезов, мап и интерфейсов? Есть ли идиоматический способ?
  3. В чем разница между nil и пустым значением (например, пустой срез []int{} vs nil)?
  4. Как избежать паники при работе с nil в функциях, которые возвращают интерфейсы?

Ожидаю получить объяснение, как безопасно работать с nil в Go, примеры идиоматического кода (паттерны вроде if err != nil для ошибок, проверка указателей перед разыменованием). Заранее спасибо!