Edited at

golang いろいろ まとめ

More than 5 years have passed since last update.


ポインタ

C/C++のポインタとはちょっと違う

C/C++の値
C/C++のポインタ
golangの値
golangのポインタ

ポインタの取り方
&val

&val

フィールド(メンバ)へのアクセス
val.member
ptr->member
val.field
ptr.field

ポインタ演算

あり

なし

参照外し

*ptr

*ptr

ダブルポインタ

&ptr

&ptr


暗黙的型変換 と 型推論が働かない場合

ここは全面的に勘違いしてたっぽいので消しておきます


メソッド

package main

type Hoge struct {}

func (h Hoge) value() {}
func (h *Hoge) pointer() {}

func main() {
val := Hoge{}
ptr := &val
}

こんなコードがあったとしてval, ptrと.value(), .pointer()の呼び出し組み合わせは次のようになります

val
ptr

.value()
ok
ok

.pointer()
ok
ok


メソッド 別の呼び出し

http://najeira.blogspot.jp/2013/12/go.html

上のurlにあるように、メソッドは次のようにしても呼び出せます

package main

type Hoge struct {}

func (h Hoge) value() {}
func (h *Hoge) pointer() {}

func main() {
val := Hoge{}

fv := Hoge.value
fv(val)

fp := (*Hoge).value
fp(&val)
}

Hoge, *Hogeと.value, .pointerの取り出し組み合わせは次のようになります

Hoge
そのときの型
*Hoge
そのときの型

.value
ok
func(Hoge)
ok
func(*Hoge)

.pointer
ng

ok
func(*Hoge)


インターフェース

次のコードはコンパイルエラーになります

package main

type Testable interface {
test()
}

type Model struct {}
func (m *Model) test() {}

func main() {
val := Model{}
ptr := &val

var tester Testable
tester = ptr // こっちは通る
tester = val // こっちはダメ

_ = tester
}

これはTestableインターフェースを実装しているのは*Model型であって

valはModel型であるのでダメということみたいです

val, ptrと実装側の組み合わせは次のようになります

val
ptr

func (m *Model)
ng
ok

func (m Model)
ok
ok


インターフェースのポインタ

http://qiita.com/suin/items/68ed7020d21dca047a73

http://qiita.com/zetamatta/items/62645bb9ad8d4cf37acb

次のコードはコンパイルエラーで落ちます

package main

type Testable interface {
test()
}

func doit(t *Testable) {
t.test()
}

func main() {
}

これは t はTestableインターフェースへのポインタであってTestableインターフェースそのものではないかららしいです

もしどうしても*Testableを使いたいなら

package main

type Testable interface {
test()
}

func doit(t *Testable) {
(*t).test()
}

func main() {
}

みたいに一回参照外しをかましてあげると通る