usar titulos tag que hacer cursiva como go null

titulos - nil detección en Go



tags h2 (5)

Veo un montón de código en Ir para detectar nada, así:

if err != nil { // handle the error }

sin embargo, tengo una estructura como esta:

type Config struct { host string port float64 }

y config es una instancia de Config, cuando lo hago:

if config == nil { }

hay un error de compilación, diciendo: no se puede convertir nada para escribir Config


Además de Oleiade, consulte la especificación sobre valores cero :

Cuando la memoria se asigna para almacenar un valor, ya sea a través de una declaración o una llamada de make o new, y no se proporciona una inicialización explícita, la memoria recibe una inicialización predeterminada. Cada elemento de dicho valor se establece en el valor cero para su tipo: falso para booleanos, 0 para enteros, 0.0 para flotantes, "" para cadenas y nulo para punteros, funciones, interfaces, sectores, canales y mapas. Esta inicialización se realiza de forma recursiva, por lo que, por ejemplo, cada elemento de una matriz de estructuras tendrá sus campos en cero si no se especifica ningún valor.

Como puede ver, nil no es el valor cero para cada tipo, sino solo para punteros, funciones, interfaces, sectores, canales y mapas. Esta es la razón por la cual config == nil es un error y &config == nil no lo es.

Para comprobar si su estructura no está inicializada, debe verificar cada miembro para su valor cero respectivo (por ejemplo, host == "" , port == 0 , etc.) o tener un campo privado que se establece mediante un método de inicialización interno. Ejemplo:

type Config struct { Host string Port float64 setup bool } func NewConfig(host string, port float64) *Config { return &Config{host, port, true} } func (c *Config) Initialized() bool { return c != nil && c.setup }


El compilador te señala el error, estás comparando una instancia de estructura y nada. No son del mismo tipo, por lo que lo consideran una comparación no válida y te grita.

Lo que quiere hacer aquí es comparar un puntero a su instancia de configuración a nil, que es una comparación válida. Para hacerlo, puede usar el nuevo comando incorporado de golang o inicializar un puntero al mismo:

config := new(Config) // not nil

o

config := &Config{host: myhost.com, port: 22} // not nil

o

var config *Config // nil

Entonces podrás verificar si

if config == nil { // then }


He creado algunos ejemplos de códigos que crean nuevas variables usando una variedad de formas que puedo pensar. Parece que las primeras 3 formas crean valores y las dos últimas crean referencias.

package main import "fmt" type Config struct { host string port float64 } func main() { //value var c1 Config c2 := Config{} c3 := *new(Config) //reference c4 := &Config{} c5 := new(Config) fmt.Println(&c1 == nil) fmt.Println(&c2 == nil) fmt.Println(&c3 == nil) fmt.Println(c4 == nil) fmt.Println(c5 == nil) fmt.Println(c1, c2, c3, c4, c5) }

qué salidas:

false false false false false { 0} { 0} { 0} &{ 0} &{ 0}


La especificación del lenguaje menciona los comportamientos de los operadores de comparación:

operadores de comparación

En cualquier comparación, el primer operando debe ser asignable al tipo del segundo operando, o viceversa.

Assignability

Un valor x se puede asignar a una variable de tipo T ("x se puede asignar a T") en cualquiera de estos casos:

  • El tipo de x es idéntico a T.
  • El tipo x de V y T tienen tipos subyacentes idénticos y al menos uno de V o T no es un tipo con nombre.
  • T es un tipo de interfaz y x implementa T.
  • x es un valor de canal bidireccional, T es un tipo de canal, x''s tipo V y T tienen tipos de elementos idénticos, y al menos uno de V o T no es un tipo con nombre.
  • x es el identificador predefinido nil y T es un puntero, función, división, mapa, canal o tipo de interfaz.
  • x es una constante sin tipo representable por un valor de tipo T.

También puede verificar como struct_var == (struct{}) . Esto no le permite comparar con cero, pero sí verifica si está inicializado o no. Tenga cuidado al usar este método. Si su estructura puede tener valores cero para todos sus campos, no tendrá mucho tiempo.

package main import "fmt" type A struct { Name string } func main() { a := A{"Hello"} var b A if a == (A{}) { fmt.Println("A is empty") // Does not print } if b == (A{}) { fmt.Println("B is empty") // Prints } }

http://play.golang.org/p/RXcE06chxE