golang断言

哆啦在这A梦在哪 · · 4136 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

类型断言 type assertion
和上节的类型转换不同,类型断言是将接口类型的值x,转换成类型T。

格式为:

x.(T)
v := x.(T)
v, ok := x.(T)

类型断言的必要条件是x是接口类型,非接口类型的x不能做类型断言:

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

T可以是非接口类型,如果想断言合法,则T应该实现x的接口。

T也可以是接口,则x的动态类型也应该实现接口T。

var x interface{} = 7  // x 的动态类型为int, 值为 7
i := x.(int)           // i 的类型为 int, 值为 7
type I interface { m() }
var y I
s := y.(string)        // 非法: string 没有实现接口 I (missing method m)
r := y.(io.Reader)     // y如果实现了接口io.Reader和I的情况下,  r的类型则为io.Reader

类型断言如果非法,运行时时候就会出现 impossible type assertion panic,为了避免这种情况,可以使用下面的语法:

v, ok = x.(T)
v, ok := x.(T)
var v, ok = x.(T)

ok代表类型断言是否合法,如果非法ok =false,v为T的零值,这样就不会出现运行时panic了。

希望你能记住,类型转换和类型断言完全是两个概念。

类型切换 type switch
类型切换(暂且这么翻译吧,英语更准确)用来比较类型而不是对值进行比较。

switch语句虽然在下一章中去讲,但是对于读者来说,多少会一种或者几种常用的编程语言,switch是一个条件语句,它可以判断某个值是否匹配某个case clause。但是对于type switch,它检查的是值x的类型T是否匹配某个类型。

格式如下,类型类型断言,但是括号内的不是某个具体的类型,而是单词type:

switch x.(type) {
// cases
}

type switch语句中可以有一个简写的变量声明,这种情况下,等价于这个变量声明在每个case clause隐式代码块的开始位置。如果case clause只列出了一个类型,则变量的类型就是这个类型,否则就是原始值的类型。

假设下面的例子中x的类型为x interface{}


switch i := x.(type) {
case nil:
  printString("x is nil") // i的类型是 x的类型 (interface{})
case int:
  printInt(i) // i的类型 int
case float64:
  printFloat64(i) // i的类型是 float64
case func(int) float64:
  printFunction(i) // i的类型是 func(int) float64
case bool, string:
  printString("type is bool or string") // i的类型是 x (interface{})
default:
  printString("don't know the type") // i的类型是 x的类型 (interface{})
}

也许你已经看到上面的例子中有一个case clause中的类型是nil,它用来匹配x为nil的interface{}的情况。

实际的例子解析使用

package main

import "log"
//创建动物接口,内部定义唱歌,跳函数
type animal interface {
    sing()
    jump()
}
//创建一个狗结构体,实现唱歌和跳函数
//狗结构体对象中,只有都实现了上述动物的内部定义,才能成功将狗定义为动物
type dog struct{}

func (m *dog) sing() {
    log.Println("dog sing")
}

func (m *dog) jump() {
    log.Println("dog jump")
}

func Judge(c interface{}) bool {
    ty, ok := c.(animal)   
    log.Println("ty:", ty)
    return ok
}
func main() {
    m := new(dog)//这里要用new申请新地址实现这个,不能使用下列这种方法

    //m := dog{}    这样得到的是一个空的dig对象,输出的是
    //2020/02/12 17:03:31 ty: <nil>
    //2020/02/12 17:03:31 false
    ok := Judge(m)
    log.Println(ok)
}

结果显示:
2020/02/12 16:54:04 ty: &{}
2020/02/12 16:54:04 true

参考文献https://colobu.com/2016/06/21/dive-into-go-6/#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80_type_assertion


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:哆啦在这A梦在哪

查看原文:golang断言

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4136 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传