これは何?
まあタイトルのとおり。
知らなかった文法・仕様・書き方がいくつかあったのでメモ。
型の別名定義
下記の、 newNameOfString
。
// = があると、C の typedef 相当。別名。
type newNameOfString = string
// = が無いと、同じ内容の別の型。
type somethingLikeString string
func (s *newNameOfString) fuga() {} //invalid receiver type *string (basic or unnamed type)
func (s *somethingLikeString) fuga() {}
func piyoFunc() {
s := "hoge"
var nns newNameOfString = s
var sls somethingLikeString = s // cannot use s (variable of type string) as somethingLikeString value
// 以下略
}
こんな機能あったっけ。
[Go] Defined type(Named type)とType aliasを使い分ける によると、go 1.9 かららしい。私が初めて触った辺りかな。
=
無しだと新しい型なのでメソッド生やしたりできる。=
有りだと単に別名なので元の型と混ぜて使える。
ビルドタグ
従来
// +build ignore
だったんだけど、いつの間にか
//go:build ignore
と書くように変わった模様。
vscode で書いていたら、format on save で急に修正されてびっくりした。
私としてはコメントであることをやめるべきだと思ってるんだけど、そこは変えないのか、と思った。
メンバを持っている匿名構造体
こういうやつ。
func anostructReceiver(ano struct{ a int }) {
}
func anostructSender() {
anostructReceiver(struct{ a int }{a: 100})
}
これはまあ、メンバー無しではよく使うから言われてみればああそうかという感じだけど、使えるかもしれないと思ったことがなかった。
struct{}
以外の匿名構造体を使いたいと思う場面に遭遇していないから気づいていなくても仕方ない。
そう思うと。
interface{}
に any
という名前がついているように、struct{}
にもなんか名前つけたらいいんじゃないかなと思う。
Defined Type の挙動
time.Duration
などで慣れている通り、defined type に対しても演算子による演算は普通にできる。
しかし構造体のメソッドは
type EmbeddedType struct{}
func (*EmbeddedType) Embedded() {}
type OriginalStruct struct {
EmbeddedType
hoge int
}
type AnotherStruct OriginalStruct
func (*OriginalStruct) Foo() {}
func structUser(o *OriginalStruct, a *AnotherStruct) {
o.Foo()
o.Embedded()
someFunc(o.hoge)
a.Foo() // a.Foo undefined (type *AnotherStruct has no field or method Foo)
a.Embedded() // これは OK
someFunc(a.hoge) // これも OK
}
Defined type からは呼べない。
元の型に埋め込まれている型へのメソッドとかは OK。
じゃあ interface はと思うと
type OriginalIF interface{ Bar() }
type AnotherIF OriginalIF
func ifUser(o OriginalIF, a AnotherIF) {
o.Bar()
a.Bar() // これは OK
}
と defined type でもメソッドが使える。
評価順序
C / C++ なんかだと
foo(bar(),baz());
の bar
と baz
が呼ばれる順序が曖昧で最適化オプションを変えると順序が変わったりする。
go の場合どうなのか知らなかったんだけど The Go Programming Language Specification - Order of evaluation を見ると
a := 1
f := func() int { a++; return a }
x := []int{a, f()} // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
などとなっていて、不定らしい。
気をつけないとね。
goto
私は書かないと思う。
type(...)
こう書いてもいいらしい。
type (
OriginalStruct struct {
EmbeddedType
hoge int
}
AnotherStruct OriginalStruct
)
見たこと無いから知らなかった。
これも書かないかな。他の人が書いていても驚かないようにしよう。
まとめ
キャッチアップちゃんとしなきゃね、と思った。