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

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

How do you make multiple interfaces reference the same value?

问题

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var a, b interface{}
  7. a = "Hi"
  8. b = &a
  9. a = *b.(*interface{})
  10. b = "Howdy"
  11. fmt.Println(a)
  12. fmt.Println(b)
  13. }

打印日志

  1. Howdy
  2. Howdy

PLAYGROUND: 点击这里

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

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var a, b interface{}
  7. a = "Hi"
  8. b = *(&a)
  9. a = *(&b)
  10. b = "Howdy"
  11. fmt.Println(a)
  12. fmt.Println(b)
  13. }

打印日志

  1. Hi
  2. 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):

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main(){
  7. var a, b any
  8. a = "Hi"
  9. b = reflect.ValueOf(&a).Elem()
  10. a = reflect.ValueOf(&b).Elem()
  11. b = "Howdy"
  12. fmt.Println(a)
  13. fmt.Println(b)
  14. }

PRINT LOGS

  1. Howdy
  2. 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...

  1. package main
  2. import (
  3. "fmt"
  4. "reflect"
  5. )
  6. func main(){
  7. var a, b any
  8. a = "Hi"
  9. b = reflect.ValueOf(&a).Elem().Interface()
  10. a = reflect.ValueOf(&b).Elem().Interface()
  11. b = "Howdy"
  12. fmt.Println(a)
  13. fmt.Println(b)
  14. }

PRINT LOGS

  1. Hi
  2. 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

简单解决方案

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

  1. package main
  2. import "fmt"
  3. func main() {
  4. var object any
  5. object = "Hi"
  6. var a, b any
  7. a = &object
  8. b = &object
  9. *a.(*any) = "Howdy"
  10. fmt.Println(*a.(*any))
  11. fmt.Println(*b.(*any))
  12. }

打印日志

  1. Howdy
  2. Howdy

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

使用多个函数

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

  1. package main
  2. import "fmt"
  3. func getStuff(a any) any {
  4. return *a.(*any)
  5. }
  6. func setStuff(a, to any) {
  7. *a.(*any) = to
  8. }
  9. func main() {
  10. var object any
  11. object = "Hi"
  12. var a, b any
  13. a = &object
  14. b = &object
  15. setStuff(a, "Howdy")
  16. fmt.Println(getStuff(a))
  17. fmt.Println(getStuff(b))
  18. }

打印日志

  1. Howdy
  2. 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:

  1. package main
  2. import &quot;fmt&quot;
  3. func main() {
  4. var object any
  5. object = &quot;Hi&quot;
  6. var a, b any
  7. a = &amp;object
  8. b = &amp;object
  9. *a.(*any) = &quot;Howdy&quot;
  10. fmt.Println(*a.(*any))
  11. fmt.Println(*b.(*any))
  12. }

PRINT LOGS

  1. Howdy
  2. 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:

  1. package main
  2. import &quot;fmt&quot;
  3. func getStuff(a any) any {
  4. return *a.(*any)
  5. }
  6. func setStuff(a, to any) {
  7. *a.(*any) = to
  8. }
  9. func main() {
  10. var object any
  11. object = &quot;Hi&quot;
  12. var a, b any
  13. a = &amp;object
  14. b = &amp;object
  15. setStuff(a, &quot;Howdy&quot;)
  16. fmt.Println(getStuff(a))
  17. fmt.Println(getStuff(b))
  18. }

PRINT LOGS

  1. Howdy
  2. 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:

确定