替换接口中golang中的指针值* a = * b

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)

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")
    }
}

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
", i)
}

type doFloat float64

func (f doFloat) Do() {
    fmt.Printf("float: %v
", 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()
}