Conceptos básicos del lenguaje Go: notas sobre el uso de nil

definición

nilNo es una palabra clave de golang, solo un nombre de variable . definido buildin/buildin.goen

// nil 是一个预先声明的标识符,表示指针、通道、函数、接口、映射或切片类型的零值。
var nil Type // 类型必须是指针、通道、函数、接口、映射或切片类型
​
// Type在这里仅用于文档目的。它是任何 Go 类型的替代品,但代表任何给定函数调用的相同类型。
type Type int
复制代码

nilIncluso podemos anularlo declarando una variable nombrada por nosotros mismos, por supuesto, esto no es recomendable.

Como se ve en los comentarios de la definición, el valor cero senil usa para representar un tipo de puntero, canal, función, interfaz, mapa o sector .

valor cero

Al declarar una variable en golang, si no la inicializamos explícitamente, a la variable se le asignará un valor cero.

tipo de datos valor cero
tipo booleano falso
Tipo numérico 0
cuerda ""
tipo de referencia nulo

Las estructuras y arreglos inicializan recursivamente sus campos o elementos, cuyos valores iniciales dependen del elemento o campo.

Pánico

asignar un valor a un puntero nulo

var i *int
*i = 1    // panic
复制代码

Solución

Asignar un bloque de memoria a un puntero nulo

var i *int
i = new(int)
*i = 1    // panic
复制代码

obtener valor de un puntero nulo

var i *int
a := *i    // panic
复制代码

Solución

Antes de asignar, verifique si el puntero está vacío

var i *int
var a int
if i != nil {
    a = *i
}
// a = 0
复制代码

Tipo de interfaz

Hay un ejemplo famoso en golang nil != nil:

var x *int
var y interface{}
fmt.Println(x == nil)    // true
fmt.Println(y == nil)    // true
fmt.Println(x == y)      // false
复制代码

Este resultado está relacionado interfacecon el principio de implementación de , y no se explicará en detalle aquí. En resumen, se interfacenecesita determinar el valor a través de typey dos atributos.value

Agregue un comentario al código anterior para que quede claro:

var x *int            // type = *int, value = nil
var y interface{}     // type = nil, value = nil
fmt.Println(x == y)   // (*int, nil) == (nil, nil) => false
复制代码

Pozo de manejo de errores

type MyError struct {}
​
func (m MyError) Error() string { return "my error" }
​
func test() error {
   var err *MyError
   return err
}
​
func main() {
   err := test()
   fmt.Println(err)           // <nil>
   fmt.Println(err == nil)    // false
}
复制代码

Encontraremos que cuando el valor de err se emite directamente, de hecho es <nil>. Al nilcomparar esto con , el resultado es nuevamente false.

Con el ejemplo anterior, sabemos que se test()cambió en el erroriginal type, lo que resultó en que el resultado del juicio final no cumpliera con las expectativas.

Supongo que te gusta

Origin juejin.im/post/6999169328558014501
Recomendado
Clasificación