.(data_type)方法到底调用/做什么? [英] What exactly does .(data_type) method called/do?

查看:99
本文介绍了.(data_type)方法到底调用/做什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了使用.(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

解决方案

b.(string)被称为 类型断言 .如 有效的Go语言 所述:

类型断言使用接口值并从中提取指定的显式类型的值.

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

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

进一步解释以消除任何可能的误会:

类型断言不会像您建议的那样告诉我b是一个字符串" .它的作用是,它将在运行时尝试从b中提取字符串,如果b包含其他类型(除非分配可选的bool值),则会出现恐慌.

从断言中获得的值确实将是string类型,允许您执行诸如切片(您无法切片接口值)或检查其len之类的事情.

I came a cross a piece of code that used .(string) method. Not knowing what this is called I had difficulties searching for it.

Here is my try to understand it:

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

}

Result:

string
string

However, I think that reflect.TypeOf takes place at run time, while .(string) would tell the compiler that b is indeed a string, and this could be used to tell the compiler that a variable is of certain type. Is my understanding right?

goplayground

解决方案

b.(string) is called a type assertion. As written in Effective Go:

A type assertion takes an interface value and extracts from it a value of the specified explicit type.

So, yes, the value you get from a type assertion is not an interface value, but is of the explicit type. You can also test if the type assertion was successful by adding an untyped boolean value:

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

Edit:

To explain further to clear out any possible misunderstanding:

A type assertion doesn't "tell Go that b is a string" as you suggested. What it does is that it will, in run time, try to extract a string from b, and panic if b contains some other type (unless assigning the optional bool value).

The value that you get from the assertion will indeed be of type string, allowing you to do things like slicing (you cannot slice an interface value) or checking its len.

这篇关于.(data_type)方法到底调用/做什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆