将结构体变量以接口类型传入函数时是否存在隐式转换?调用test函数发生了什么?
问题分析与解答
示例代码
package main import "fmt" type usb interface { isok() } type phone struct { } func (p phone) isok() { } func test(u usb) { fmt.Printf("typeof u : %T\n", u) var _, ok = u.(usb) if ok { fmt.Printf("typeof u : usb\n") } } func main() { var p = phone{} test(p) }
运行输出
typeof u : main.phone typeof u : usb
提问
将实现usb接口的phone结构体变量传入参数类型为usb接口的test函数时,是否存在隐式转换?调用该函数时具体发生了什么?
解答
1. 是否存在隐式转换?
存在隐式转换。当把phone类型变量传给usb接口类型参数时,Go会自动将phone值转换为usb接口类型的值,这个过程无需手动编写转换代码,是隐式完成的。
2. 调用函数时的具体过程
- 接口值构造:Go的接口值包含两个核心部分——类型指针和数据指针。当
phone变量传入test函数时,Go会生成一个usb类型的接口值:类型指针指向main.phone的类型元信息,数据指针指向传入的phone实例副本(因为phone是值类型,传递时会先复制实例)。 - 类型打印逻辑:
%T格式化符会读取接口值中存储的实际类型,也就是main.phone,这是第一行输出的原因。u.(usb)是类型断言操作,这里断言的是接口值本身属于usb接口类型,而接口值天然符合其自身的接口类型定义,因此断言成功,输出第二行内容。
- 参数传递细节:由于
phone是值类型,传入函数时会先复制一份phone实例,再将这个副本包装成usb接口值,最终传递给test函数的参数u。
内容的提问来源于stack exchange,提问作者relax
相关产品推荐
相关产品推荐

