关键字类型在交换机中使用时的含义是什么?

can*_*dry 13 go

我在golang中看到过这个代码的几个实例:

func process(node ast.Node) Foo {
    switch n := node.(type) {
        // ... removed for brevity
    }
}
Run Code Online (Sandbox Code Playgroud)

ast.Node是一个界面.是node.(type)代码段来执行反射; 找出界面的实际实现者?

Den*_*ret 11

是.它被称为Type开关.它允许您根据所传递的接口的实际类型执行代码.

我认为官方文档及其示例很清楚:

交换机还可用于发现接口变量的动态类型.这种类型的开关使用括号内的关键字类型的类型断言的语法.如果switch在表达式中声明了一个变量,则该变量将在每个子句中具有相应的类型.在这种情况下重用名称也是惯用的,实际上声明了一个具有相同名称但在每种情况下具有不同类型的新变量.

var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
    fmt.Printf("unexpected type %T", t)       // %T prints whatever type t has
case bool:
    fmt.Printf("boolean %t\n", t)             // t has type bool
case int:
    fmt.Printf("integer %d\n", t)             // t has type int
case *bool:
    fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
    fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
Run Code Online (Sandbox Code Playgroud)

您不应该在正确输入的程序中经常使用它,但在需要时它很方便.使用示例:假设您实现了数据库驱动程序,您可能必须根据Go变量的类型进行转换.这是go-sql/mysql驱动程序的摘录:

// Scan implements the Scanner interface.
// The value type must be time.Time or string / []byte (formatted time-string),
// otherwise Scan fails.
func (nt *NullTime) Scan(value interface{}) (err error) {
    if value == nil {
        nt.Time, nt.Valid = time.Time{}, false
        return
    }

    switch v := value.(type) {
    case time.Time:
        nt.Time, nt.Valid = v, true
        return
    case []byte:
        nt.Time, err = parseDateTime(string(v), time.UTC)
        nt.Valid = (err == nil)
        return
    case string:
        nt.Time, err = parseDateTime(v, time.UTC)
        nt.Valid = (err == nil)
        return
    }

    nt.Valid = false
    return fmt.Errorf("Can't convert %T to time.Time", value)
}
Run Code Online (Sandbox Code Playgroud)