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

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

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

问题

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

package main

import (
	"log"
)

type i interface {
	replace(s2 i)
}

type s1 struct {
	id int
}

func (s *s1) replace(s2 i) {
	*s = *s2.(*s1)
}

type s2 struct {
	id float64
}

func (s *s2) replace(s2 i) {
	*s = *s2.(*s2)
}

func test(s i, s2 i) {
	s.replace(s2)
}

func main() {
	s := &s1{1}
	s2 := &s2{2.0}
	log.Println(s, s2)
	test(s, s2)
	log.Println(s, s2)
}

这段代码无法编译通过:

./test.go:16: invalid indirect of s2 (type i)
./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

package main

import (
    "log"
)

type s1 struct {
    id int
}

func (s *s1) replace(s2 *s1) {
    *s = *s2
}

func test(s *s1, s2 *s1) {
    s.replace(s2)
}

func main() {
    s := &s1{1}
    s2 := &s1{2}
    log.Println(s, s2)
    test(s, s2)
    log.Println(s, s2)
}

The result is

2015/04/09 16:57:00 &{1} &{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?

package main

import (
    "log"
)

type i interface {
    replace(s2 i)
}

type s1 struct {
    id int
}

func (s *s1) replace(s2 i) {
    *s = *s2
}

type s2 struct {
    id float64
}

func (s *s2) replace(s2 i) {
    *s = *s2
}

func test(s i, s2 i) {
    s.replace(s2)
}

func main() {
    s := &s1{1}
    s2 := &s2{2.0}
    log.Println(s, s2)
    test(s, s2)
    log.Println(s, s2)
}

This does not compile

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

答案1

得分: 4

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

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

func (s *s1) replace(swap i) {
    switch t := swap.(type) {
    case *s1:
        *s = *t
    default:
        panic("not the same type")
    }
}
英文:

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

func (s *s1) replace(swap i) {
	switch t := swap.(type) {
	case *s1:
		*s = *t
	default:
		panic("not the same type")
	}
}

答案2

得分: 0

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

package main

import "fmt"

type Doer interface {
	Do()
}

type doInt int

func (i doInt) Do() {
	fmt.Printf("int: %v\n", i)
}

type doFloat float64

func (f doFloat) Do() {
	fmt.Printf("float: %v\n", f)
}

func swap(to, from *Doer) {
	*to = *from
}

func main() {
	var d1 Doer = doInt(1)
	var d2 Doer = doFloat(1.1)

	var d *Doer

	d = &d1

	(*d).Do()
	swap(d, &d2)
	(*d).Do()
}

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

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

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

package main

import "fmt"

type Doer interface {
	Do()
}

type doInt int

func (i doInt) Do() {
    fmt.Printf("int: %v\n", i)
}

type doFloat float64

func (f doFloat) Do() {
	fmt.Printf("float: %v\n", f)
}

func swap(to, from *Doer) {
	*to = *from
}

func main() {
    var d1 Doer = doInt(1)
    var d2 Doer = doFloat(1.1)

    var d *Doer

    d = &d1

    (*d).Do()
    swap(d, &d2)
    (*d).Do()
}

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

func main() {
    var d Doer = doInt(1)
    d.Do()	
    d = doFloat(1.1) // swapped!
    d.Do()
}

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:

确定