golangを基礎から学ぶ 関数編

  • 46
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

関数は複数の戻り値をもつことができる

golangの目新しい特徴のひとつとして数えられている。
関数は、括弧でリストすることで複数の値を持かえすことができる。返された値は、変数リストへ代入して格納する。
(int, int) が返す値を括弧でリストしている部分。
func 関数名 引数 戻り値 の順番になる。

func f(a int, b int) (int, int) {
    c := a + b
    d := a * b
    return c, d     
}

func main() {
    a := 100
    b := 100
    c,d := f(a, b)
    fmt.Println(c)
    fmt.Println(d)
}

output

200
10000

戻り値を複数定義できる形式はエラーハンドリングにも一役かっている

func doSomething(input int) (result string, err error) {
    switch {
    case input < 0:
        return "", fmt.Errorf("%d is minus value", input)
    case input < 10:
        return "less than 10", nil
    default:
        return "greater than 10", nil
    }
}

func main() {
    if r, err := doSomething(-1); err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(r)
    }
}

output

-1 is minus value

匿名関数

golangは匿名関数をサポートしている

funcから始まる関数リテラルは匿名関数をあらわし、変数に代入することが可能。

func main() {
    fn := func() {
        fmt.Println("hello")
    }
    fn()
}

output

hello

匿名関数を関数の引数にとしてわたすことも可能

func sumOf(f func(int) int, n, m int) int {
    a := 0
    for ; n <=  m; n++ {
        a += f(n)
    }
    return a
}

func main() {
    square := func(x int) int { return x * x }
    fmt.Println(square(10))
    a := func(x int) int { return x * x }(10)
    fmt.Println(a)
    fmt.Println(sumOf(square, 1, 100))
    fmt.Println(sumOf(func(x int) int { return x * x }, 1, 100))
}

output

100
100
338350
338350

クロージャ

関数リテラルはクロージャになっている。
そのため関数リテラル内から外側の関数内で定義した変数を参照可能になる。
これらの変数は外側の関数と、関数リテラル間で共有され、これらからアクセス可能な限り存続する。

func main() {
    x := 5
    fn := func() {
        fmt.Println("x is", x)
    }
    fn()
    x++
    fn()
}

output

x is 5
x is 6
func intSeq() func() int {
    i := 0
    return func() int {
        i += 1
        return i
    }
}

func main() {
    nextInt := intSeq()

    fmt.Println(nextInt())
    fmt.Println(nextInt())
    fmt.Println(nextInt())
    newInts := intSeq()
    fmt.Println(newInts())
}

output

1
2
3
1

参考

golang で複数のエラーをハンドリングする方法

お気楽 Go 言語プログラミング入門

Function Types in Go (golang)