クロージャにメソッドを実装してみる - Go

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

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

実際にやってみる

  • クロージャもカスタム定義型にキャストしたりすればメソッド(インターフェース)を実装することができる
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 を実装したことになる

まとめ

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

comments powered by Disqus