GO 类型断言

在Go语言中,我们可以使用type switch语句查询接口变量的真实数据类型,语法如下:

switch x.(type) {
// cases
}

x必须是接口类型。

来看一个详细的示例:

type Stringer interface {
    String() string
}

var value interface{} // Value provided by caller.
switch str := value.(type) {
case string:
    return str //type of str is string
case Stringer: //type of str is Stringer
    return str.String()
}

语句switch中的value必须是接口类型,变量str的类型为转换后的类型。

If the switch declares a variable in the expression, the variable will have the corresponding type in each clause. It's also idiomatic to reuse the name in such cases, in effect declaring a new variable with the same name but a different type in each case.
如果我们只关心一种类型该如何做?如果我们知道值为一个string,只是想将它抽取出来该如何做?只有一个case的类型switch是可以的,不过也可以用类型断言(type assertions)。类型断言接受一个接口值,从中抽取出显式指定类型的值。其语法借鉴了类型switch子句,不过是使用了显式的类型,而不是type关键字,如下:

x.(T)

同样,x必须是接口类型。

str := value.(string)

上面的转换有一个问题,如果该值不包含一个字符串,则程序会产生一个运行时错误。为了避免这个问题,可以使用“comma, ok”的习惯用法来安全地测试值是否为一个字符串:

str, ok := value.(string)
if ok {
    fmt.Printf("string value is: %q\n", str)
} else {
    fmt.Printf("value is not a string\n")
}

如果类型断言失败,则str将依然存在,并且类型为字符串,不过其为零值,即一个空字符串。
我们可以使用类型断言来实现type switch的中例子:

if str, ok := value.(string); ok {
    return str
} else if str, ok := value.(Stringer); ok {
    return str.String()
}

这种做法没有多大实用价值。

posted @ 2017-05-17 13:52  sysnap  阅读(2212)  评论(0编辑  收藏  举报