はじめに
Goのソースコードを読んでいて、構造体関連で new
や New
をよく見かけていたのですが、それぞれの意味や違いをあまり理解していなかったので、それらを調べたときのメモです。
new
newは指定した型のポインタ型を生成する関数です。
例えば、構造体型のポインタ型を生成できます。
newを使った初期化
type person struct {
height float32
weight float32
}
func main() {
p := new(person)
p.height = 182.0
p.weight = 75.5
fmt.Println(p) // &{182 75.5}
fmt.Printf("%T", p) // *main.person person型のポインタであることがわかる
fmt.Println()
fmt.Printf("%p", p) // 0xc00001e060 もちろんアドレスもある
}
構造体型のポインタ型を生成する手段としては、他にアドレス演算子を使う方法もあります。どちらも動作上殆ど同じです。
アドレス演算子を使った初期化
func main() {
p := &person{height: 182.0, weight: 75.5}
fmt.Println(p) // &{182 75.5}
}
構造体の初期化する際は、構造体のフィールドを参照共有するために newを使う方法
か アドレス演算子を使う方法
のいずれかでポインタ型にすることが多いかなと思います。
また、newは構造体以外の値型にも参照型の変数にも使用できます。
しかしながら、このような使用は普段のソフトウェア開発では滅多にありません。現実的には構造体とnewはセットで使うことが多いです。
func main() {
a := new(int)
fmt.Println(a) // 0xc00001e060
}
New
Goにはコンストラクタが用意されていません。
しかし、コンストラクタのようなものは実装できます。その時の関数名として通例、 New + 構造体名
が適用されます。
type person struct {
height float32
weight float32
}
func NewPerson(height, weight float32) *person{
return &person{height: height, weight: weight}
}
func main() {
p := NewPerson(182.0, 75.5)
fmt.Println(p) // &{182 75.5}
}
まとめ
- newは構造体の初期化でよく使う
- Newはコンストラクタの単なる命名における慣例