我在Go中看到了很多检测nil的代码,像这样:
if err != nil {
// handle the error
}
然而,我有一个像这样的结构:
type Config struct {
host string
port float64
}
和config是config的一个实例,当我这样做:
if config == nil {
}
有编译错误,说: 不能将nil转换为Config类型
我在Go中看到了很多检测nil的代码,像这样:
if err != nil {
// handle the error
}
然而,我有一个像这样的结构:
type Config struct {
host string
port float64
}
和config是config的一个实例,当我这样做:
if config == nil {
}
有编译错误,说: 不能将nil转换为Config类型
当前回答
你也可以检查像struct_var == (struct{})。它不允许你与nil进行比较,但是它可以检查它是否初始化了。使用这种方法时要小心。如果你的结构体的所有字段都是零值,你就没有时间了。
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
其他回答
编译器将错误指向你,你在比较一个结构实例和nil。它们不是同一类型的,所以它认为这是一个无效的比较,并对你大喊大叫。
这里要做的是将指向配置实例的指针与nil进行比较,这是一个有效的比较。要做到这一点,你可以使用golang new内置,或者初始化一个指向它的指针:
config := new(Config) // not nil
or
config := &Config{
host: "myhost.com",
port: 22,
} // not nil
or
var config *Config // nil
然后你就能检查是否
if config == nil {
// then
}
在Go 1.13及以后的版本中,您可以使用Value。反射包中提供的IsZero方法。
if reflect.ValueOf(v).IsZero() {
// v is zero, do something
}
除了基本类型,它还适用于Array, Chan, Func, Interface, Map, Ptr, Slice, UnsafePointer和Struct。参考这个。
你也可以检查像struct_var == (struct{})。它不允许你与nil进行比较,但是它可以检查它是否初始化了。使用这种方法时要小心。如果你的结构体的所有字段都是零值,你就没有时间了。
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
我已经创建了一些示例代码,使用我能想到的各种方式创建新变量。看起来,前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}
语言规范中提到了比较操作符的行为:
比较运算符
在任何比较中,第一个操作数必须可赋值给该类型 第二个操作数的,反之亦然。
可转让性
A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases: x's type is identical to T. x's type V and T have identical underlying types and at least one of V or T is not a named type. T is an interface type and x implements T. x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type. x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type. x is an untyped constant representable by a value of type T.