如何使多个接口引用相同的值?

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

How do you make multiple interfaces reference the same value?

问题

我想让两个接口引用相同的值(也就是说,如果你更新其中一个,另一个也会更新为相同的内容):

package main

import (
    "fmt"
)

func main() {
    var a, b interface{}

    a = "Hi"

    b = &a
    a = *b.(*interface{})

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

打印日志

Howdy
Howdy

PLAYGROUND: 点击这里

这段代码可以按预期工作,除了ab不是接口类型。所以当我将它们转换为接口类型时...

package main

import (
    "fmt"
)

func main() {
    var a, b interface{}

    a = "Hi"

    b = *(&a)
    a = *(&b)

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

打印日志

Hi
Howdy

PLAYGROUND: 点击这里

...这段代码不再按预期工作。

有没有一种方法可以使用接口数据类型而不是reflect.Value数据类型,并且保持两个接口引用相同的值?

英文:

I would like to make two interfaces reference the same value (meaning if you update one, the other will update to the same thing):

package main

import (
    "fmt"
    "reflect"
)

func main(){
    var a, b any

    a = "Hi"

    b = reflect.ValueOf(&a).Elem()
    a = reflect.ValueOf(&b).Elem()

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

PRINT LOGS

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/qizVO42UaUj

This code works as intended, aside from the fact that a and b are not interfaces. So when I convert them to interfaces like so...

package main

import (
    "fmt"
    "reflect"
)

func main(){
    var a, b any

    a = "Hi"

    b = reflect.ValueOf(&a).Elem().Interface()
    a = reflect.ValueOf(&b).Elem().Interface()

    b = "Howdy"

    fmt.Println(a)
    fmt.Println(b)
}

PRINT LOGS

Hi
Howdy

PLAYGROUND: https://go.dev/play/p/jCpuepBJYdD

...the code no longer works as intended.

Is there a way to use the interface data type rather than the reflect.Value data type while maintaining that the two interfaces reference the same value?

答案1

得分: 0

简单解决方案

找到了解决方法,不需要使用反射。通过将值的地址存储在接口中,可以通过使用类型断言到接口指针并解引用来实现:

package main

import "fmt"

func main() {
	var object any
	object = "Hi"

	var a, b any
	a = &object
	b = &object

	*a.(*any) = "Howdy"

	fmt.Println(*a.(*any))
	fmt.Println(*b.(*any))
}

打印日志

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/LEx8MR4ZK06

使用多个函数

如果你想要抽象出类型断言和解引用的过程:

package main

import "fmt"

func getStuff(a any) any {
	return *a.(*any)
}

func setStuff(a, to any) {
	*a.(*any) = to
}

func main() {
	var object any
	object = "Hi"

	var a, b any
	a = &object
	b = &object

	setStuff(a, "Howdy")

	fmt.Println(getStuff(a))
	fmt.Println(getStuff(b))
}

打印日志

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/RUX4cu2Cx2o

英文:

<h1>Simple Solution</h1>

Figured it out—no need to use reflection. Storing the value's address in the interface will allow you to accomplish this by using a type assertion to an interface pointer and dereferencing:

package main

import &quot;fmt&quot;

func main() {
	var object any
	object = &quot;Hi&quot;

	var a, b any
	a = &amp;object
	b = &amp;object

	*a.(*any) = &quot;Howdy&quot;

	fmt.Println(*a.(*any))
	fmt.Println(*b.(*any))
}

PRINT LOGS

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/LEx8MR4ZK06

<h1>Using Multiple Functions</h1>

If you would like to abstract away the type-assertion and derefencing:

package main

import &quot;fmt&quot;

func getStuff(a any) any {
	return *a.(*any)
}

func setStuff(a, to any) {
	*a.(*any) = to
}

func main() {
	var object any
	object = &quot;Hi&quot;

	var a, b any
	a = &amp;object
	b = &amp;object

	setStuff(a, &quot;Howdy&quot;)

	fmt.Println(getStuff(a))
	fmt.Println(getStuff(b))
}

PRINT LOGS

Howdy
Howdy

PLAYGROUND: https://go.dev/play/p/RUX4cu2Cx2o

huangapple
  • 本文由 发表于 2022年9月14日 03:06:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/73708149.html
匿名

发表评论

匿名网友

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

确定