在下面的代码片段中,我想了解iPerson当其内容仍未初始化时究竟存储了什么:只是一个 0 字节的值?或者它实际上是引擎盖下的指针(当然也初始化为 0 字节)?在任何情况下,究竟发生了iPerson = person什么?如果iPerson = person复制person,那么当一个实现IPerson但具有不同大小/内存占用的对象被分配给 时会发生iPerson什么?我的理解iPerson是一个存储在堆栈上的变量,所以它的大小必须是固定的。这是否意味着堆实际上是在底层使用的,所以iPerson实际上是作为指针实现的,但赋值仍然复制对象,如上面的代码所示?这是代码:type Person struct{ name string }type IPerson interface{}func main() { var person Person = Person{"John"} var iPerson IPerson fmt.Println(person) // => John fmt.Println(iPerson) // => <nil> ...so looks like a pointer iPerson = person // ...this seems to be making a copy fmt.Println(iPerson) // => John person.name = "Mike" fmt.Println(person) // => Mike fmt.Println(iPerson) // => John ...so looks like it wasn't a pointer, // or at least something was definitely copied}
3 回答
吃鸡游戏
TA贡献1829条经验 获得超7个赞
你问为什么
iPerson = person
iPerson = &person
被允许。它们都是允许的,因为 person 和 &person 都实现了 IPerson 接口。这是显而易见的,因为 IPerson 是空接口——每个值都实现它。
确实,您无法静态确定 IPerson 的值是持有指针还是值。所以呢?关于 IPerson,您只知道存储在该类型值中的任何对象都实现了接口中的方法列表。假设这些方法已正确实施。IPerson 是否持有值或指针与此无关。
例如,如果该方法要更改存储在对象中的某些内容,那么该方法几乎必须是一个指针方法,在这种情况下,只能在接口类型的变量中存储一个指针值。但是如果没有任何方法改变存储在对象中的内容,那么它们都可以是值方法,并且可以在变量中存储非指针值。
哆啦的时光机
TA贡献1779条经验 获得超6个赞
当您执行以下行时:
iPerson = person
您正在Person
接口变量中存储一个值。由于对结构的赋值执行复制,是的,您的代码正在复制。要从接口内部检索结构,您需要获取另一个副本:
p := iPerson.(Person)
所以你很少想用可变类型来做这件事。如果您想在接口变量中存储指向结构的指针,则需要显式执行此操作:
iPerson = &person
就引擎盖下发生的事情而言,接口变量分配堆空间来存储大于指针的值是正确的,但这通常对用户不可见。
- 3 回答
- 0 关注
- 269 浏览
添加回答
举报
0/150
提交
取消