replace pointer value *a = *b in golang for interface

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

replace pointer value *a = *b in golang for interface

问题

可以使用*s = *s2.(*s1)*s = *s2.(*s2)来替换不同类型但具有相同接口的两个变量的指针值。

  1. package main
  2. import (
  3. "log"
  4. )
  5. type i interface {
  6. replace(s2 i)
  7. }
  8. type s1 struct {
  9. id int
  10. }
  11. func (s *s1) replace(s2 i) {
  12. *s = *s2.(*s1)
  13. }
  14. type s2 struct {
  15. id float64
  16. }
  17. func (s *s2) replace(s2 i) {
  18. *s = *s2.(*s2)
  19. }
  20. func test(s i, s2 i) {
  21. s.replace(s2)
  22. }
  23. func main() {
  24. s := &s1{1}
  25. s2 := &s2{2.0}
  26. log.Println(s, s2)
  27. test(s, s2)
  28. log.Println(s, s2)
  29. }

这段代码无法编译通过:

  1. ./test.go:16: invalid indirect of s2 (type i)
  2. ./test.go:24: invalid indirect of s2 (type i)
英文:

It's possible to replace pointer value using *a = *b for two variables of same type

  1. package main
  2. import (
  3. "log"
  4. )
  5. type s1 struct {
  6. id int
  7. }
  8. func (s *s1) replace(s2 *s1) {
  9. *s = *s2
  10. }
  11. func test(s *s1, s2 *s1) {
  12. s.replace(s2)
  13. }
  14. func main() {
  15. s := &s1{1}
  16. s2 := &s1{2}
  17. log.Println(s, s2)
  18. test(s, s2)
  19. log.Println(s, s2)
  20. }

The result is

  1. 2015/04/09 16:57:00 &{1} &{2}
  2. 2015/04/09 16:57:00 &{2} &{2}

Is it possible to achieve the same for two variables of different type but same interface?

  1. package main
  2. import (
  3. "log"
  4. )
  5. type i interface {
  6. replace(s2 i)
  7. }
  8. type s1 struct {
  9. id int
  10. }
  11. func (s *s1) replace(s2 i) {
  12. *s = *s2
  13. }
  14. type s2 struct {
  15. id float64
  16. }
  17. func (s *s2) replace(s2 i) {
  18. *s = *s2
  19. }
  20. func test(s i, s2 i) {
  21. s.replace(s2)
  22. }
  23. func main() {
  24. s := &s1{1}
  25. s2 := &s2{2.0}
  26. log.Println(s, s2)
  27. test(s, s2)
  28. log.Println(s, s2)
  29. }

This does not compile

  1. ./test.go:16: invalid indirect of s2 (type i)
  2. ./test.go:24: invalid indirect of s2 (type i)

答案1

得分: 4

不管它们是否具有相同的接口,*s1*s2是不同的类型,不能互相赋值。

如果你想通过接口来交换相同类型的值,你可以在方法中添加类型断言:

  1. func (s *s1) replace(swap i) {
  2. switch t := swap.(type) {
  3. case *s1:
  4. *s = *t
  5. default:
  6. panic("not the same type")
  7. }
  8. }
英文:

It doesn't matter if they have the same interface, *s1 and *s2 are different types, and can't be assigned to one another.

If you want to be able to swap the same type through the interface, you can add a type assertion to the method

  1. func (s *s1) replace(swap i) {
  2. switch t := swap.(type) {
  3. case *s1:
  4. *s = *t
  5. default:
  6. panic("not the same type")
  7. }
  8. }

答案2

得分: 0

你可以通过接口指针交换接口的底层值,如果你想要的话:

  1. package main
  2. import "fmt"
  3. type Doer interface {
  4. Do()
  5. }
  6. type doInt int
  7. func (i doInt) Do() {
  8. fmt.Printf("int: %v\n", i)
  9. }
  10. type doFloat float64
  11. func (f doFloat) Do() {
  12. fmt.Printf("float: %v\n", f)
  13. }
  14. func swap(to, from *Doer) {
  15. *to = *from
  16. }
  17. func main() {
  18. var d1 Doer = doInt(1)
  19. var d2 Doer = doFloat(1.1)
  20. var d *Doer
  21. d = &d1
  22. (*d).Do()
  23. swap(d, &d2)
  24. (*d).Do()
  25. }

但是更简单的方法是直接这样赋值给接口:

  1. func main() {
  2. var d Doer = doInt(1)
  3. d.Do()
  4. d = doFloat(1.1) // swapped!
  5. d.Do()
  6. }
英文:

You can swap the underlying values of interfaces via pointers to interfaces, if you want:

  1. package main
  2. import "fmt"
  3. type Doer interface {
  4. Do()
  5. }
  6. type doInt int
  7. func (i doInt) Do() {
  8. fmt.Printf("int: %v\n", i)
  9. }
  10. type doFloat float64
  11. func (f doFloat) Do() {
  12. fmt.Printf("float: %v\n", f)
  13. }
  14. func swap(to, from *Doer) {
  15. *to = *from
  16. }
  17. func main() {
  18. var d1 Doer = doInt(1)
  19. var d2 Doer = doFloat(1.1)
  20. var d *Doer
  21. d = &d1
  22. (*d).Do()
  23. swap(d, &d2)
  24. (*d).Do()
  25. }

But it is much easier to simply assign to the interface like this:

  1. func main() {
  2. var d Doer = doInt(1)
  3. d.Do()
  4. d = doFloat(1.1) // swapped!
  5. d.Do()
  6. }

huangapple
  • 本文由 发表于 2015年4月10日 01:07:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/29544765.html
匿名

发表评论

匿名网友

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

确定