[Introduction]断言:判断类型/类型转换

326 阅读2分钟

在阅读之前,建议先行阅读从学习assert的用法开始理解如何写“专业的程序”

断言

断言Type Assertion是编程术语,表示为布尔表达式

类型断言的必要条件时待判断类型必须是接口,否则无法断言:

var i int = 10
v := i.(int) // 错误

[Introduction]接口/空接口中提到了空接口的使用方式,一个类型在通过in interface{}的方式传递进来的时候,自动转为interface{}空接口的类型,其原因是所有类型都实现了空接口。在参数传递的时候常常需要使用空接口,例如:

func funcA(in interface{}) string {
     return string(in)
}

此时编译器将返回:

cannot convert a (type interface{}) to type string: need type assertion

因为此时没有进行类型断言,对于判断一个空接口储存到底为何种类型时有以下三种方法:

直接断言

如果断言的类型是一个具体类型如string,类型断言x.(T)就检查x的动态类型是否和T的类型相同:

var unknow interface{}
unknow = "unknowtype"
val, ok := unknow.(string) // return true , unknow is string ; unknow赋值给val

如果断言的类型T是一个接口类型,类型断言x.(T)检查x的动态类型是否满足T接口

反射

在上一篇...中,也可以使用反射来确定类型。反射需要import reflect使用包内方法判断类型:

retType = reflect.TypeOf(unknow)
val = reflect.ValueOf(unknow)

type关键字判断

和直接断言类似,使用swich-case语句来判断是否为某一类型

switch unknow.(type){
    case string:
        // string类型
    case int:
        // int类型
}

类型转换

对于空接口赋值的类不能直接调用其内部方法,需要进行类型转换后转换为相应的类后才可以调用内部的方法:

import (
    "fmt"
)

type Name struct {
    string
}

func (name Name) hello() {
    fmt.Println(name.string)
}

func main() {
    var name interface{} = new(Name)
    //name.hello()  这是错误的
    f := name.(Name)
    f.hello()
}

参考链接

Golang断言的使用

从学习assert的用法开始理解如何写“专业的程序”

空接口断言类型的判断