英文:
go - function to write to an interface{}
问题
我想在不知道其类型的情况下,将一个指针传递给函数,并让函数对其进行写入。以下是我认为会起作用的代码:
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest.(*int) = 1
// 处理其他情况...
}
}
然而,使用*int
输入调用此函数的结果是编译器错误:
invalid indirect of dest (type interface {})
。
我在这里做错了什么?
英文:
I want to pass a pointer to something into a function, without knowing its type at compile time, have the function write to it. Here's what I thought would work:
func foo(dest interface{}) {
switch (dest).(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
However, calling this with an *int
input
func main() {
bar := 2
foo(&bar)
fmt.Println(bar) // expect 1
}
yields the compiler error
invalid indirect of dest (type interface {})
.
What am I doing wrong here?
答案1
得分: 7
在这段代码中(顺便说一句,你不需要在dest
周围加上括号),一旦进入一个case,你基本上忘记了类型:
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// 处理其他情况...
}
}
也就是说,根据编译器的说法,dest
仍然是interface{}
类型,这使得*dest = 1
是错误的。
你可以像这样使用更多的类型断言...
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest.(*int) = 1
// 处理其他情况...
}
}
...但是一个实际“记住”类型的switch会更好(来自Effective Go):
func foo(dest interface{}) {
switch dest := dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// 处理其他情况...
}
}
英文:
In this piece of code (btw, you don't need the parens around dest
), you are basically forgetting the type once you enter a case:
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
That is, dest is still of type interface{} according to the compiler, and that makes *dest = 1
wrong.
You could use more type assertions like this...
func foo(dest interface{}) {
switch dest.(type) {
case *int:
fmt.Println("got int")
*dest.(*int) = 1
// handle other cases...
}
}
...but a switch that actually 'remembers' the type would be much better (from Effective Go)
func foo(dest interface{}) {
switch dest := dest.(type) {
case *int:
fmt.Println("got int")
*dest = 1
// handle other cases...
}
}
答案2
得分: 1
dest仍然是类型为interface{}
。在赋值过程中,你也必须对其进行类型转换:
*dest.(*int) = 1
英文:
dest is still of type interface{}
. You have to cast it during the assignment as well:
*dest.(*int) = 1
答案3
得分: 0
这个问题似乎有点旧,但我找到了一种更通用的处理方法,可以使用反射来处理。虽然它不如其他解决方案快,但可以适用于传递给函数的任何其他类型。
func foo(dest interface{}) {
destVal := reflect.ValueOf(dest)
val := reflect.ValueOf(1)
if destVal.Kind() == reflect.Ptr && destVal.Elem().Kind() == val.Kind() {
if destElem := destVal.Elem(); destElem.CanSet() {
destElem.Set(val)
}
}
}
英文:
This question seems a bit old, but I have come along a more general way to handle this using reflection, it's not as fast as other solutions but it works with any other types you pass to the function
func foo(dest interface{}) {
destVal := reflect.ValueOf(dest)
val := reflect.ValueOf(1)
if destVal.Kind() == reflect.Ptr && destVal.Elem().Kind() == val.Kind() {
if destElem := destVal.Elem(); destElem.CanSet() {
destElem.Set(val)
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论