2013年12月11日水曜日

Golang Cafe #7を開催しました。

Golang Cafe #7を開催しました。

今回は、+Takanobu Haginoさんの疑問に答えた後、+Ryuji Iwataさんの発表資料のお披露目があったので見させて頂いたのと、Go1.2の変更点を幾つか紹介した流れとなりました。

+Takanobu Haginoさんの疑問
  1. C#のdecimalに対応するものは何か?
  2. 演算子のオーバーロードなどの機能は?
  3. 変数の型が何かを知る方法は?
私が知るかぎりでは、2は、Goには存在しません。理由は速度に影響があるのか、複雑になるからなのかはわかりませんが…。

1は、math.big.Intとか、math.big.Ratを利用するしかありませんが、これはJavaのBigDecimalのようにメソッドを呼び出さないと計算ができないので少々面倒なのですが、この問題を解決しているのがC#のdecimal型なんですよね…。

3は、Go1.2からfmtパッケージの書式が増えて、%Tが指定できるようになっています。これを使えば型の名前を出力する事ができます。Debugなどで使えば便利だと思います。プログラムで判定するなどしたい場合は、switch文の中で、変数名.(type)の記述をすることで判定が可能です。型を実際に取得する場合はreflectパッケージを利用する歯科なさそうです。

次に、+Ryuji Iwataさんのプレゼンですが…発表当日をお楽しみに!

最後に私からGo1.2の変更点について、nilの扱いとThree-Index-Slices、fmtパッケージの変更点について紹介しました。

最初のnilの扱いについて。

package main

import (
        "fmt"
)

type T struct {
        Field1 int32
        Field2 int32
}

type T2 struct {
        X [1<<24]byte
        Field int32
}

func main() {
        var x *T
        p1 := &x.Field1
        p2 := &x.Field2
        var x2 *T2
        p3 := &x2.Field

        fmt.Println(x2.X[0])        
        fmt.Println(p1, p2, p3)
}

上記のようにnilポインタの変数のメンバを参照した時に1.1の時はアクセスできていたようなのですが、1.2からはpanicになるように変更されました。ただ、実際に動かしてみるとどちらもpanicになったような…。
現時点では、nilポインタアクセスさせるということがないので、いまいちわかりませんでした。変な事はしないということが重要ですね。

次に、

        var arr [10]int

        for i := 0; i < len(arr); i++ {
                arr[i] = i + 1
        }

        slice := arr[2:4:7]
        //slice := arr[2:4:4]

        var slice2 []int = slice
        for i := 0; i < 5; i++ {
                slice2 = append(slice2, 11 + i)
        }

        fmt.Println(slice, len(slice), cap(slice), arr, slice2, cap(arr))

上記のように、sliceを取得する時に、3つ目の値を指定することで、容量を取得する事ができるようになりました。実際にappendしていくと、参照元のarrの値が容量いっぱいまで更新されるようになります。また、確保される容量は、7-2=5となります。7個確保されるわけではなく、2番目から7番目までの容量という意味で捉えるといいでしょう。
上記の結果だと、1 2 3 4 11 12 13 8 9 0という配列になります。slice側は容量よりも大きくなっても値は保持されます。
sliceなので、元の配列arrの容量には影響は与えませんでした。値のみ影響されるようです。
以前は、容量の指定がなかったので、まちがって編集すると元もすべて影響をうけていましたが、容量指定のおかげで、少なくとも、容量よりも大きな添字の値は守られるようになっています。

fmtパッケージの変更点は、型名が出力される%Tの他に、出力する引数の番号を指定できるようになりました。%[1]dという指定をします。開始番号は1です。
%[3]d %d %dとすると、2番目の省略した所は、4番目を参照しようとします。したがって、省略したら指定した番号の次を出力という動きをしています。

次回のGolang Cafe #8は、今年のGo言語の振り返りと来年以降の動向を聞いてみようと思います。4年もたった言語ですからそろそろ大きな飛躍があると思いますので…。