如何使用interface{}将整数作为指针传递给函数?

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

How to pass integer as pointer using interface{} to function

问题

我以为这是一件简单的事情,但我错了。我不能使用interface{}integer作为指针传递给函数。

示例:

var test int
someChange(&test)
fmt.Printf("函数之后:%d", test)

func someChange(i interface{}) error{
    newFunnyValue := 42
    i = newFunnyValue
    fmt.Printf("来自someChange的问候,现在test的值是:%d" , i)
    return nil //更改成功,返回nil
}

结果为:

来自someChange的问候,现在test的值是:42 
函数之后:0

我读到interface{}类似于void*,所以上面的代码应该可以工作,但实际上不行,为什么?我想补充一下,如果我传递的是一个结构体对象,一切都正常工作。

我需要将int包装在某个结构体中吗?

编辑:

https://play.golang.org/p/rg1vabug0P

英文:

I thought this is a simple thing to do, but I was wrong. I can't pass integer as pointer to function using interface{}.

Example:

var test int
someChange(&test)
fmt.Printf("after function: %d", test)

func someChange(i interface{}) error{
	newFunnyValue := 42
	i = newFunnyValue
	fmt.Printf("hello from someChange now value test is: %d" , i)
	return nil //change gone ok, so nil
}

And result:

 hello from someChange now value test is: 42 
 after function: 0

I read that interface{} is similar to void* so above code should work but it's not, why? I want to add that if I pass some object which is a struct, everything works good.

Do I have to wrap int in some struct?

Edit:

https://play.golang.org/p/rg1vabug0P

答案1

得分: 3

如果你想观察someChange()函数外部的变化(在test变量中),你必须修改指向的值(给它赋一个新值)。你没有这样做,你只是给i参数赋了一个新值(它是someChange()函数内部的局部变量)。

你可以使用类型断言i接口变量中获取*int指针,然后可以给指向的值赋一个新值。

示例:

func someChange(i interface{}) error {
    newFunnyValue := 42
    if p, ok := i.(*int); ok {
        *p = newFunnyValue
        return nil //change gone ok, so nil
    }
    return errors.New("Not *int")
}

测试:

var test int
someChange(&test)
log.Printf("after function: %d", test)

输出(在Go Playground上尝试):

2009/11/10 23:00:00 after function: 42

请注意,将int值或*int指针包装在结构体中是不必要的,如果你没有给指向的对象赋一个新值,它不会有任何区别。

英文:

If you want to observe the change outside of the someChange() function (in the test variable), you must modify the pointed value (assign a new value to it). You're not doing that, you just assign a new value to the i parameter (which is a local variable inside someChange()).

You may obtain the *int pointer from the i interface variable using type assertion, and then you can assign a new value to the pointed value.

Example:

func someChange(i interface{}) error {
	newFunnyValue := 42
	if p, ok := i.(*int); ok {
		*p = newFunnyValue
		return nil //change gone ok, so nil
	}
	return errors.New("Not *int")
}

Testing it:

var test int
someChange(&test)
log.Printf("after function: %d", test)

Output (try it on the Go Playground):

2009/11/10 23:00:00 after function: 42

Note that wrapping the int value or the *int pointer in a struct is unnecessary and it wouldn't make a difference if you're not assigning a new value to the pointed object.

答案2

得分: 1

ifunc someChange()中仍然是interface{}类型。在赋值过程中,你需要对其进行类型转换:

*i.(*int) = 42
英文:

i is still of type interface{} within the func someChange(). You have to cast it during the assignment:

*i.(*int) = 42

huangapple
  • 本文由 发表于 2016年12月29日 07:18:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/41371060.html
匿名

发表评论

匿名网友

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

确定