I'm new to golang and I want to implement an overloaded method something similar to C++ overloading, and my code looks something like this:
type someStruct struct {
val int
some string
}
type object interface {
toByte()
}
// someStruct implementing an object interface
func (s *someStruct) toByte() {
}
func overload(overLoadedObj interface{}) {
switch str := overLoadedObj .(type) {
case string:
fmt.Println("string : ", str)
case int:
fmt.Println("int : ", str)
case object: //* It doesn't come here at all*
fmt.Println("interface obj", str)
}
}
func main() {
overload("hello")
overload(5)
overload(someStruct{val: 5, some: "say"})
}
So the question is:
How to make sure that whoever implements object interface will fall in at case object type ?
Thanks in advance.
The "problem" is that someStruct.toByte()
has a pointer receiver. This means the method toByte()
belongs to the type *someStruct
and not to someStruct
. So someStruct
does not implement object
, only *someStruct
. And you pass a value of someStruct
to overload()
.
Pass a value of *someStruct
, and you'll get what you want:
overload(&someStruct{val: 5, some: "say"})
Output (try it on the Go Playground):
string : hello
int : 5
interface obj &{5 say}
Relevant section from the spec: Method sets:
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type
T
consists of all methods declared with receiver typeT
. The method set of the corresponding pointer type*T
is the set of all methods declared with receiver*T
orT
(that is, it also contains the method set ofT
).
Note that behind the scenes when you call overload()
like this:
overload(&someStruct{val: 5, some: "say"})
This will wrap the *someStruct
pointer value in an interface{}
value (because overload()
has a parameter of interface{}
type), and not in an interface value of type object
.
Inside overload()
, the type switch will check types in the listed order. And when it reaches case object
, it will see that the value wrapped in the overLoadedObj
parameter does implement object
so this case will be executed.