返回介绍

interface 变量存储的类型

发布于 2024-10-12 12:35:55 字数 2537 浏览 0 评论 0 收藏 0

interface 的变量里面可以存储任意类型的数值(该类型实现了 interface)。那么怎么反向知道这个变量里面实际保存了的是哪个类型的对象呢?目前常用的有两种方法:

  • Comma-ok 断言

Go 语言里面有一个语法,可以直接判断是否是该类型的变量: value, ok = element.(T),这里 value 就是变量的值,ok 是一个 bool 类型,element 是 interface 变量,T 是断言的类型。

如果 element 里面确实存储了 T 类型的数值,那么 ok 返回 true,否则返回 false。

通过一个例子来更加深入的理解。

package main
import (
    "fmt"
    "strconv"
)
type Element interface{}
type List [] Element
type Person struct {
    name string
    age int
}
//定义了 String 方法,实现了 fmt.Stringer
func (p Person) String() string {
    return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"
}
func main() {
    list := make(List, 3)
    list[0] = 1 // an int
    list[1] = "Hello" // a string
    list[2] = Person{"Dennis", 70}
    for index, element := range list {
        if value, ok := element.(int); ok {
            fmt.Printf("list[%d] is an int and its value is %d\n", index, value)
        } else if value, ok := element.(string); ok {
            fmt.Printf("list[%d] is a string and its value is %s\n", index, value)
        } else if value, ok := element.(Person); ok {
            fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)
        } else {
            fmt.Printf("list[%d] is of a different type\n", index)
        }
    }
}

是否注意到了多个 if 里面,if 里面允许初始化变量。断言的类型越多,那么 if else 也就越多,所以才引出了下面要介绍的 switch。

  • switch 测试

重写上面的这个实现

package main
import (
    "fmt"
    "strconv"
)
type Element interface{}
type List [] Element
type Person struct {
    name string
    age int
}
//打印
func (p Person) String() string {
    return "(name: " + p.name + " - age: "+strconv.Itoa(p.age)+ " years)"
}
func main() {
    list := make(List, 3)
    list[0] = 1 //an int
    list[1] = "Hello" //a string
    list[2] = Person{"Dennis", 70}
    for index, element := range list{
        switch value := element.(type) {
            case int:
            fmt.Printf("list[%d] is an int and its value is %d\n", index, value)
            case string:
            fmt.Printf("list[%d] is a string and its value is %s\n", index, value)
            case Person:
            fmt.Printf("list[%d] is a Person and its value is %s\n", index, value)
            default:
            fmt.Println("list[%d] is of a different type", index)
        }
    }
}

这里有一点需要强调的是: element.(type) 语法不能在 switch 外的任何逻辑里面使用,如果要在 switch 外面判断一个类型就使用 comma-ok

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文