Go's method is curried funtion
Yasuhiro Matsumoto
Nov 21, 2017
Go's method is not same as one in other languages. In C++, this
should not be null.
class Foo {
public:
void doSomething() {}
};
int
main() {
Foo *foo = nullptr;
foo->doSomething();
}
Go's one doesn not require that the receiver is instanciated.
package main
import (
"fmt"
)
type Foo struct {
}
func (f *Foo) doSomething() {
fmt.Println(f)
}
func main() {
var foo *Foo
foo.doSomething()
}
And Go's method hold the receiver value. This is called Method Values.
package main
import (
"fmt"
)
type Foo struct {
Value string
}
func (f *Foo) WhatsUp() {
fmt.Println(f.Value)
}
func doSomething(f func()) {
f()
}
func main() {
foo := &Foo{Value: "Hello, World"}
doSomething(foo.WhatsUp)
}
The WhatsUp
is evaulated with the receiver.
package main
import (
"fmt"
)
type Foo int
func (f Foo) doSomething() {
fmt.Println(f)
}
func main() {
Foo.doSomething(123)
}
So this code is valid. Foo.doSomething
is the function object. So you can call it with let the function object to a variable. The function type should take an first argument which is type of the receiver.
package main
import (
"fmt"
)
type Foo int
func (f Foo) doSomething() {
fmt.Println(f)
}
func main() {
var fn func(Foo)
fn = Foo.doSomething
fn(123)
}
This idiom is useful to call runtime.SetFinalizer
to Close
something resource must be closed.
package main
import (
"log"
"os"
"runtime"
"myresource"
)
func main() {
f := myresource.OpenSomethingMustBeClosed()
if err != nil {
log.Fatal(err)
}
runtime.SetFinalizer(f, (*myresource.Writer).Close)
}