go – 写入接口的函数{}

huangapple go评论84阅读模式
英文:

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)
		}
	}
}

example

huangapple
  • 本文由 发表于 2015年8月15日 20:21:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/32024660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定