在Go中没有检测

我看到很多代码在检测零,如下所示:

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

不过,我有这样的结构:

 type Config struct { host string port float64 } 

config是Config的一个实例,当我这样做的时候:

 if config == nil { } 

有编译错误,说:不能将nil转换成typesconfiguration

编译器将错误指向你,你正在比较一个结构实例和nil。 他们不是同一types,所以认为这是一个无效的比较,并大声对你。

你想在这里做的是比较一个指向你的configuration实例的指针为零,这是一个有效的比较。 要做到这一点,你可以使用golang 内build,或初始化一个指针:

 config := new(Config) // not nil 

要么

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

要么

 var config *Config // nil 

那么你将能够检查是否

 if config == nil { // then } 

除Oleiade以外,请参阅零值规格 :

当分配内存来存储一个值时,无论是通过声明还是调用make或new,并且不提供显式的初始化,内存都被赋予一个默认的初始化。 这样一个值的每个元素的types设置为零值:布尔值为false,整数为0,浮点数为0.0,string为“”,指针,函数,接口,片,通道和映射为零。 这个初始化是recursion地完成的,例如,如果没有指定值,那么结构数组中的每个元素都会将其字段置零。

正如你所看到的, nil不是每个types的零值,而只是指针,函数,接口,片,通道和地图的零值。 这就是为什么config == nil是错误而&config == nil不是。

为了检查你的结构是否是未初始化的,你必须检查每个成员是否有相应的零值(例如host == ""port == 0等)或者有一个由内部初始化方法设置的私有字段。 例:

 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 } 

我已经创build了一些示例代码,它使用我能想到的各种方法创build新的variables。 它看起来像前3种方式创造价值,最后两种创造参考。

 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) } 

其输出:

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

你也可以检查像struct_var == (struct{}) 。 这不允许你比较零,但它确实检查它是否被初始化。 使用这种方法时要小心。 如果你的结构的所有字段都可以有零值 ,你就不会有太多的时间。

 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

语言规范提到了比较运算符的行为:

比较运营商

在任何比较中,第一个操作数必须可分配给第二个操作数的types,反之亦然。


可转让性

在任何这些情况下,值x都可分配给types为T的variables(“x可分配给T”):

  • x的types与T相同
  • x的typesV和T具有相同的基础types,并且V或T中的至less一个不是命名types。
  • T是一个接口types,x实现T.
  • x是双向通道值,T是通道types,x的typesV和T具有相同的元素types,并且V或T中的至less一个不是命名types。
  • x是预先标识的标识符nil,T是指针,函数,片,映射,通道或接口types。
  • x是由typesT的值表示的无types常量。