为什么可以将引用类型分配给不满意的接口[golang]

I find interface satisfiability between value type and reference type confusing. I still cannot figure out how it works in golang. Consider this piece of program:

type Counter1 int
type Counter2 int

func (c Counter1) String() string {

}

func (c *Counter2) String() string {

}

func main() {
    var c1 Counter1
    var c2 Counter2
    var i1 fmt.Stringer = &c1 // assignment 1
    var i2 fmt.Stringer = c2 // assignment 2
}

However assignment 1 works but assignment 2 doesn't. I expected none of them works: Type Counter1 satisfies fmt.Stringer however type *Counter1 doesn't. So &c1 should not be assignable to i1; Type Counter2 doesn't satisfy fmt.Stringer however type *Counter2 does, so c2 should not be assignable to i2 and actually it cannot. The outcome of this test program doesn't make sense to me. I thought it might be some kind of syntactic sugar where go compiler converts between reference type and value type automatically. However the following piece of test code makes me more confused:

type Test interface {
    f()
    g()
}

func (c Counter1) f() {
}

func (c *Counter1) g() {
}

func receiveTest(t Test) {
}

func main() {
    ......
    var c3 Counter1
    var p3 Test = &c3 // works
    receiveTest(&c3) // works
    receiveTest(c3) // doesn't work
}

Neither type *Counter1 nor type Counter1 satisfies interface Test. However first and second assignment still works. It doesn't make sense to me.

In Go, a selector expression (x.f) denotes the field or method f of the value x (or sometimes *x).

Basically, in Go, if you have a pointer receiver on a method, you do not have to write &object.method(), but you can just write object.method()

https://play.golang.org/p/nh8X-vwdfr

https://play.golang.org/p/1uKwZw6E-J

Because interfaces are implicit in Go, as long as the object itself is not a pointer, then it doesn't matter if the methods that satisfy the interface have pointer receivers or not, they will still be used to satisfy it.

So, in your example, a Counter1 struct can have both f() and g() methods called on it, but a *Counter1 can only have a g() method called on it.