再帰

Go の関数は再帰呼び出しをサポートしている。よくある階乗を求めるプログラムを見てみよう。

package main

import "fmt"

func fact(n int) int {
    if n == 0 {
        return 1
    } else {
        return n * fact(n - 1)
    }
}

func main() {
    for i := 0; i < 13; i++ {
        fmt.Println(i, ":", fact(i))
    }
}
^o^ > go run fact.go
0 : 1
1 : 1
2 : 2
3 : 6
4 : 24
5 : 120
6 : 720
7 : 5040
8 : 40320
9 : 362880
10 : 3628800
11 : 39916800
12 : 479001600

func で定義した関数でなく匿名関数でも、先に関数を代入する変数を宣言しておけば、再帰呼び出しができる。

package main

import "fmt"

func main() {
    var fact func(int) int
    fact = func(n int) int {
        if n == 0 {
            return 1
        } else {
            return n * fact(n - 1)
        }
    }

    for i := 0; i < 13; i++ {
        fmt.Println(i, ":", fact(i))
    }
}
^o^ > go run fact2.go
0 : 1
1 : 1
2 : 2
3 : 6
4 : 24
5 : 120
6 : 720
7 : 5040
8 : 40320
9 : 362880
10 : 3628800
11 : 39916800
12 : 479001600

匿名関数については、また改めて書く。

スライスのコピー

copy 関数を使う。コピー元のスライスより、コピー先のほうが長い場合はもちろん、短い場合でもエラーにならない。長さはコピー先のスライスに合わせられる。

package main

import "fmt"

func main() {
    a := []int{ 1,2,3,4,5,6,7,8 }
    b := []int{ 10,20,30,40,50,60,70,80,90,100 }
    c := []int{ 10,20,30,40 }
    fmt.Println(a)
    fmt.Println(b)
    fmt.Println(c)

    copy(b, a)
    copy(c, a)
    fmt.Println(b)
    fmt.Println(c)
}
^o^ > go run slice_copy.go
[1 2 3 4 5 6 7 8]
[10 20 30 40 50 60 70 80 90 100]
[10 20 30 40]
[1 2 3 4 5 6 7 8 90 100]
[1 2 3 4]