英文:
How to make nil interface to struct in golang
问题
我是你的中文翻译助手,以下是代码的翻译:
我是Golang的新手。
我执行了下面的代码。最后得到了一个空的humans数组。
在函数F中我应该做什么?
为了测试(猴子补丁)的目的,我必须按照原始函数的调用方式进行操作。
package main
import (
"fmt"
)
type Human struct {
Name string
}
type Cat struct {
Name string
}
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
arr = arr.(*[]*Human)
case *[]*Cat:
arr = &[]*Cat{{Name: "meow"}}
arr = arr.(*[]*Cat)
}
}
func main() {
var humans []*Human
F(&humans)
fmt.Println(humans)
var cats []*Cat
F(&cats)
fmt.Println(cats)
}
希望对你有帮助!
英文:
I'm new in Golang.
I executed the code below. I get empty humans array in the end.
What should I do in func F?
For testing(monkeypatch) sake. I have to follow the way how the origin func is called.
package main
import (
"fmt"
)
type Human struct {
Name string
}
type Cat struct {
Name string
}
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
arr = arr.(*[]*Human)
case *[]*Cat:
arr = &[]*Cat{{Name: "meow"}}
arr = arr.(*[]*Cat)
}
}
func main() {
var humans []*Human
F(&humans)
fmt.Println(humans)
var cats []*Cat
F(&cats)
fmt.Println(cats)
}
答案1
得分: 2
答案和主要问题的原因是,当参数传递给函数或赋值给变量时,Go 总是使用按值传递(或值的副本)。
你的函数 F
接受一个 arr
参数:
func F(arr interface{}) {
//...
}
当从你的 main
函数调用时,你传递了一个 []*Human
指针作为参数,这些值将被复制并传递给你的函数 F
进行执行。
回到你的函数 F
的主体,arr
将具有由 main
传递的相同值,这恰好是指向原始 []*Human
结构体的地址。在给 arr
赋予新值时:
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
// ...
}
}
你正在将新值赋给 局部 的 arr
变量,而不是原始指针,原始指针保持不变。
要更新参数指针所指向的值,你应该使用 解引用
符号:
func F(arr interface{}) {
switch arr := arr.(type) {
case *[]*Human:
*arr = []*Human{&Human{Name: "abc"}}
fmt.Println(arr)
// ...
}
}
> 注意 switch arr := arr.(type)
语句,它创建一个新的 arr
变量(遮蔽了参数 arr
),并具有 interface
的动态类型,以便能够为其分配适当的值。
英文:
The answer, and the main issue cause as well, is that Go always uses pass by value (or copy of the value) when arguments are passed around to function or assigned to variables.
Your function F
takes an arr
argument:
func F(arr interface{}) {
//...
}
When called from your main
function, you are passing an []*Human
pointer as an argument, which values will be copied and fed to your function F
for execution.
Going back to your function F
body, the arr
will be having the same value passed by main, which happens to be the address to the original []*Human
struct. Upon assigning a new value to arr
:
func F(arr interface{}) {
switch arr.(type) {
case *[]*Human:
arr = &[]*Human{{Name: "abc"}}
// ...
}
}
You are assigning a new value to the local arr
variable and not to the original pointer, which remains, indeed, unchanged.
To update the value toward which the argument pointer is referring to, you should used the dereferrence
symbol:
func F(arr interface{}) {
switch arr := arr.(type) {
case *[]*Human:
*arr = []*Human{&Human{Name: "abc"}}
fmt.Println(arr)
// ...
}
}
> Note the switch arr := arr.(type)
statement which creates a new arr
variable (shadowing the argument arr
) with the interface
dynamic type to be able to assign the proper value to it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论