This question is not as clear as I wanted to be I will ask a better question. But I do not want to marked duplicate on that. So I have flagged my own question. If you can help it to be deleted to not confuse the community. Please do the needful. Please do not downvote me while you are at it. Sorry to be unclear
I am new to golang and just getting the hang of it.
I am learning by taking Tour of Go and then using it with my own understanding. I was at Interfaces and started to implement with my own understanding. Here is Go PlayGround Link
Step 1 : I made 3 types an int, a struct and an interface
package main
import (
"fmt"
)
type MyInt int
type Pair struct {
n1, n2 int
}
type twoTimeable interface {
result() (int, int)
}
Step 2 : Then I implemeted twoTimeable for pointer receivers because it changes underlying value.
func (p *Pair) result() (int, int) {
p.n1 = 2 * p.n1
p.n2 = 2 * p.n2
return p.n1, p.n2
}
func (m *MyInt) result() (int, int) {
*m = 2 * (*m)
return int(*m), 0
}
Step 3 : Then I declared and assigned MyInt, Pair and their corresponding pointers in main function. I also declared twoTimeable interface
mtemp := MyInt(2)
var m1 MyInt
var m2 *MyInt
var p1 Pair
var p2 *Pair
m1, m2, p1, p2 = MyInt(1), &mtemp, Pair{3, 4}, &Pair{5, 6}
var tt twoTimeable
fmt.Println(" Values : ", m1, *m2, p1, *p2, tt)
Step 4 : The I assigned MyInt,Pair and their pointers , called the implemented method and printed.
tt = m1
fmt.Println(tt.result())
fmt.Printf("Value of m1 %v\n", m1)
tt = m2
fmt.Println(tt.result())
fmt.Printf("Value of m2 %v\n", *m2)
tt = p1
fmt.Println(tt.result())
fmt.Printf("Value of p1 %v\n", p1)
tt = p2
fmt.Println(tt.result())
fmt.Printf("Value of p2 %v\n", *p2)
It shows error :
prog.go:41:5: cannot use m1 (type MyInt) as type twoTimeable in assignment:
MyInt does not implement twoTimeable (result method has pointer receiver)
prog.go:49:5: cannot use p1 (type Pair) as type twoTimeable in assignment:
Pair does not implement twoTimeable (result method has pointer receiver)
I also read this question, I got that m1 and p1 are not addressable, thats why it wont compile.
But method result() will just work fine if I use p1, or m1 p1/m1.result()
(auto dereferencing FTW)
Now in Step 2 when I change the pointer receiver to value receiver, and change *m to m(I am aware of change in Output)
func (p Pair) result() (int, int) {
p.n1 = 2 * p.n1
p.n2 = 2 * p.n2
return p.n1, p.n2
}
func (m MyInt) result() (int, int) {
m = 2 * (m)
return int(m), 0
}
It suddenly does not show compile error. shouldn't it for m2 and p2, because now there is no implementation of result using *MyInt and *Pair
That means if interface method implementation has value receiver tt can hold both pointer and value. But when interface method implemenation has pointer reciever it cant hold non pointers.
Q1 : Why it is fine to use pointers (tt = m2) on value receiver interface methods(p MyInt) result() , but not values (tt = m1) on pointer receiver interface method(p *MyInt) result().
Now lets revert to pointer receivers.
Is there a way that if function accept param (tt twoTimeable) i will be able to invoke tt.result() irrespective tt being a pointer to type or not, given result() is only definded with pointer receiver.
See the code below:
func doSomething(tt twoTimeable) {
temp1, temp2 := tt.result()
fmt.Print("doing something with ", temp1, temp2)
}
Since tt can be any predefined type(pointer or not a pointer), accpting param (tt *twoTimeable, if I can even do that) does not seem like a solution or do I have rely on user of function to provide pointer. If i do not have to change underlying value i.e use value receiver its not a problem as tt can hold either value or pointer to that
I always Accept answer.