究竟是什么。(data_type)方法调用/ do?

时间:2015-03-09 15:43:28

标签: go

我遇到了一段使用.(string)方法的代码。我不知道这叫什么,我很难找到它。

我试图理解它:

package main

import "fmt"
import "reflect"

func main(){
    var b interface{}
    b = "silly"

    fmt.Println(reflect.TypeOf(b.(string))) // we know that b 
                                            // is a string                     
                                            // at compile time

    fmt.Println(reflect.TypeOf(b))          // we do not

}

结果:

string
string

但是,我认为reflect.TypeOf发生在运行时,而.(string)会告诉编译器b确实是一个字符串,这可以用来告诉编译器变量属于某种类型。我的理解是对的吗?

goplayground

2 个答案:

答案 0 :(得分:11)

b.(string)被称为 type assertion 。如 Effective Go

中所述
  

类型断言接受一个接口值,并从中提取指定显式类型的值。

所以,是的,从类型断言获得的值不是接口值,而是显式类型。您还可以通过添加无类型布尔值来测试类型断言是否成功:

s, ok := b.(string) // s is of type string
if !ok {
    // b did not contain a value of type string!
}

修改

进一步解释清除任何可能的误解:

类型断言不会"告诉Go b b是一个字符串" 如你所建议的那样。它的作用是在运行时尝试从b中提取字符串,如果b包含其他类型,则会发生混乱(除非指定可选的bool值)。

从断言获得的值确实是string类型,允许您执行切片(不能切片接口值)或检查其len等内容。

答案 1 :(得分:1)

之前的答案是正确的。但我提交的内容更像是在实践中发生的事情。 。(类型)语法通常与交换机的类型名称一起使用。在此示例中,I(整数expr),B(bool expr)和Bop(二进制op)是类型名称。

func commute (e Expr) (r Expr, d bool) {
    switch exp:= e.(type) {
        case I: r,d = exp,false
        case B: r,d = exp,false
        case Bop: r,d = Bop{exp.op, exp.right, exp.left},true
        default: r,d = e,false
    }
    return
}

这不像C演员一样不安全,因为在case语句中你保证匹配类型。在阅读频道时我会看到这一点,其中频道的类型是所有案例实现的接口。