初识nil

在 Go 语言中,nil 是一个预定义的标识符,表示某些类型的零值或空值。它和 Java 的 null 有相似之处,但也有一些关键区别。

Go 中的 nil

  1. nil 的适用类型

    • 指针(Pointer):未指向任何内存地址的指针。
    • 切片(Slice):未初始化的切片(底层数组未分配)。
    • 映射(Map):未初始化的映射(底层哈希表未分配)。
    • 通道(Channel):未初始化的通道。
    • 函数(Function):未初始化的函数变量。
    • 接口(Interface):未赋值或值为 nil 的接口变量。
  2. nil 的行为

    • 指针:解引用 nil 指针会导致 panic。
    • 切片nil 切片可以安全调用 len()cap()(返回 0),但尝试访问元素会 panic。
    • 映射nil 映射不能存储键值对,尝试写入会 panic。
    • 通道nil 通道发送或接收会永久阻塞。
    • 接口:接口变量为 nil 时调用方法会 panic(除非动态类型的方法允许 nil 接收者)。
  3. nil 的特殊性

    • Go 的 nil 不是关键字,而是一个预定义的标识符。
    • nil 没有默认类型,必须显式或隐式与某种类型关联。

Java 中的 null

  1. null 的适用类型

    • 所有引用类型(对象、数组等)都可以是 null
    • 基本类型(int, float, boolean 等)不能为 null
  2. null 的行为

    • 访问 null 对象的成员(方法或字段)会抛出 NullPointerException
    • null 可以赋值给任何引用类型变量。

主要区别

特性 Go 的 nil Java 的 null
适用类型 指针、切片、映射、通道、函数、接口 所有引用类型(对象、数组等)
基本类型支持 Go 无“基本类型”概念,所有类型可为 nil(如果允许) 基本类型(int 等)不能为 null
安全性 部分操作允许(如 len(nil切片)),部分会 panic 几乎所有操作都会抛出 NullPointerException
语义 表示“零值”或“未初始化”状态 表示“无引用”
是否为关键字 不是关键字,是预定义标识符 是关键字

示例对比

Go 的 nil

var s []int         // nil 切片
fmt.Println(len(s)) // 输出 0(不会 panic)

var m map[string]int // nil 映射
// m["key"] = 1      // 会 panic

var p *int           // nil 指针
// fmt.Println(*p)   // 会 panic

Java 的 null

String str = null;
// System.out.println(str.length()); // 抛出 NullPointerException

int[] arr = null;
// System.out.println(arr[0]);       // 抛出 NullPointerException

总结

  • 相同点:都表示“无值”或“未初始化”状态。
  • 不同点
    • Go 的 nil 更结构化,不同类型有不同行为,部分操作是安全的。
    • Java 的 null 更统一,几乎所有操作都会抛出异常。
    • Go 的 nil 可以用于更多类型(如函数、通道),而 Java 的 null 仅用于引用类型。

Go 的 nil 设计更注重类型安全,而 Java 的 null 更简单直接,但容易引发 NullPointerException

posted on 2025-04-04 08:34  Leo-Yide  阅读(59)  评论(0)    收藏  举报