新品と新品の違い
# 開発ノートgolang には make と new という二つの予約語があり、特にゴランを初めて学ぶときに混同しやすい部分です。ここでは簡単なメモを作成しました。
new
new はジェネリックを初期化するために使用でき、メモリのアドレスを返します。通常、私たちは new を使った後にポインタ変数を使って型を受け取ります。特に注意が必要なのは、new は自動的に型をゼロ初期化することです。つまり、文字列は ""、数値は 0、チャネル、関数、マップ、スライスなどは nil になります。
この特性から、もしマップに対して以下の操作を行うと、panic: assignment to entry in nil map というエラーが発生します。
func main() {
people := new(map[string]string)
p := *people
p["name"] = "Kalan" // panic: assignment to entry in nil map
}
初期化されたマップは nil マップになるため、他のプリミティブ型のようにデフォルト値が存在しません。
もし struct を使って初期化する場合、& を使ってポインタのアドレスを直接示すこともできます。以下の二つの書き方は同じ効果があります。
type Person struct {
Name string
Age int
}
func main() {
p := &Person{}
p := new(Person)
}
上記の Person は、渡したい値に応じて追加の設定が可能ですが、new は全てのフィールドをゼロ初期化します。
make
make は new とは異なり、チャネル、マップ、スライスなどの特別な型を初期化するために使用されます。また、make はポインタを返さないことに特に注意が必要です。ポインタを取得する必要がある場合は、new のような方法で型を初期化することを考慮しなければなりません。
func main() {
receiver := make(chan string) // チャネルを初期化しますが、ポインタは返しません
person := make(map[string]string)
people := make([]string, 100) // 長さ100の文字列配列を初期化
}
再度強調しますが、**make はポインタを返しません!**以下のコードはエラーを引き起こします。
func main() {
person := make(map[string]string)
fmt.Println(*person) // invalid indirect of person
}
結論
make と new はゴランを学び始める際に混同しやすく、時には引数をポインタで渡さなければならないときにうっかり make を使ってしまうこともあります。この二つの違いを理解することが非常に重要です。
もっと読む
関連記事
- Access Keyはもう使うなAccess KeyはAWSで見落とされがちなセキュリティリスクだ。OIDCとIAM Roleを組み合わせれば、GitHub Actionsはsecretなしで安全にAWSリソースを操作できる
- データベースの主キー: AUTO_INCREMENT、UUID、UUIDv7バックエンド開発では主キーをどうするかをよく決める必要がある。auto increment か UUID か、衝突はどうするか、UUIDv7 と created_at + index の性能差はどれくらいか。実際に 2000 万件のデータで検証し、設計判断までまとめる。
- Zeabur を使ってみた一般的な独立開発者がサービスをデプロイする際には、Vercelのようなプラットフォームを選択することが多いですが、データベース接続のようなより高度なニーズが必要になると、Vercelはあまり便利ではありません。また、一般的なクラウドサービスプロバイダーの価格は独立開発者にとって高額です。この記事では、Zeaburを使用した際の体験を共有し、皆さんにおすすめします!
- キーボードについて - ファームウェア編本篇為 IT 2023 鐵人賽文章:鍵盤入坑指南 - 韌體篇