そろそろスピリチュアルなエントリから脱却して Golang について書こうと思います。最近仕事で少し触っていたり、昨日「Go Conference 2014 spring 」にも参加してきたりで Golang に対するモチベーションが上がっているので、少しずつアウトプットしていこうかと。

今回はクロージャ周りで「お。。そうか〜こんなこともできるんか〜」っと思ったことについてメモ。


実際にやってみる

  • クロージャもカスタム定義型にキャストしたりすればメソッド(インターフェース)を実装することができる
package main

import (
	"fmt"
)

type MyFunction func() string

func (f MyFunction) String() string {
	return "poyo"
}

func main() {
	function := func() string {
		return "piyo"
	}
	fmt.Println(function)   // 0x22d0
	fmt.Println(function()) // piyo

	myFunction := MyFunction(function)
	fmt.Println(myFunction)   // poyo
	fmt.Println(myFunction()) // piyo
}
  • 上記の例ではクロージャを fmt.Stringer インターフェースを実装した MyFunction にキャストすることで、fmt.Println で出力できるようにしている
  • こんなパターンどこで使うの…?と思ったりもするけれど、net/http の http.HandleFunc がそれっぽいことをしている
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "piyo!")
	})
	http.ListenAndServe(":4000", nil)
}
  • 上記の例では http.HandleFunc の第二引数としてクロージャを渡しているが、これはさらに http.ServeMux.HandlerFunc に渡されて http.HandlerFunc にキャストされる
  • http.HandlerFuncServeHTTP というメソッドを実装しているので、渡したクロージャは結果的に ServeHTTP を実装したことになる


まとめ

絶対使いこなせないけど、知ってるといいことあってほしい