Home About
Golang , Kotlin , Functional Programming

Golang や Kotlin で関数の型を定義する

Go言語では first class functions とやらで、関数はファーストクラスオブジェクトであり値のように使うことができる。 そして、この関数の型(どんな型を引数にとってどんな型を返す、という情報)に名前をつけることができる。

コードにすればこれだけのことです。

main.go:

package main

import "fmt"

type SayHelloFunc func(name string) string

func outputSayHello(f SayHelloFunc, name string) {
	greeting := f(name)
	fmt.Println(greeting)
}

func createAnotherJaSayHelloFunc() SayHelloFunc {
	return func(name string) string {
		return fmt.Sprintf("やあ %s さん!", name)
	}
}

func main() {
	// 1)
	enSayHelloFunc := func(name string) string {
		return fmt.Sprintf("Hello %s!", name)
	}

	outputSayHello(enSayHelloFunc, "Taro")

	// 2)
	jaSayHelloFunc := func(name string) string {
		return fmt.Sprintf("%s さん こんにちは!", name)
	}

	outputSayHello(jaSayHelloFunc, "太郎")

	// 3)
	outputSayHello(createAnotherJaSayHelloFunc(), "太郎")
}

文字列を引数にとり文字列を返す関数 SayHelloFunc :: String -> String を定義しただけ。

実行する:

$ go run main.go
Hello Taro!
太郎 さん こんにちは!
やあ 太郎 さん!

type で関数の型を宣言するときに:

type SayHelloFunc func(name string) string

以下のように = を入れても問題ないようです。

type SayHelloFunc = func(name string) string

func(name string) string に SayHelloFunc という別名を付けているだけと考えると = があった方がわかりやすような気もする。

kotlin では typealias で定義できた

kotlin でも 関数はファーストクラスオブジェクト 扱いなので、関数の定義だけできるのか調べたら普通にできた。 typealias を使う。

main.kts:

typealias SayHelloFunc = (String)-> String

val enSayHelloFunc: SayHelloFunc = { name->
	"Hello ${name}!"
}

val jaSayHelloFunc: SayHelloFunc = { name->
	"こんにちは ${name}!"
}

println( enSayHelloFunc("Taro") )
println( jaSayHelloFunc("Taro") )
$ kotlinc -script main.kts 
Hello Taro!
こんにちは Taro!