structの概要
構造体の定義と利用 Goの予約語 | ||
struct 概要 |
||
|
基本的なstructの使い方
以下のコードは、struct
を使って人物の情報を管理する例です。
package main
import "fmt"
// 構造体の定義
type Person struct {
Name string
Age int
}
func main() {
// 構造体のインスタンスを作成
p := Person{Name: "太郎", Age: 25}
// フィールドにアクセス
fmt.Println("名前:", p.Name)
fmt.Println("年齢:", p.Age)
}
解説:
Person
という構造体を定義し、Name
(文字列)とAge
(整数)のフィールドを持たせます。p := Person{Name: "太郎", Age: 25}
のようにフィールドを指定してインスタンスを作成します。p.Name
やp.Age
を使ってフィールドの値にアクセスできます。
実行結果:
名前: 太郎 年齢: 25
ポインタを使った構造体の参照
構造体は値型ですが、ポインタを使うと参照渡しが可能になります。
package main
import "fmt"
type Person struct {
Name string
Age int
}
func changeAge(p *Person, newAge int) {
p.Age = newAge // ポインタを介してフィールドを更新
}
func main() {
p := Person{Name: "花子", Age: 30}
fmt.Println("変更前の年齢:", p.Age)
changeAge(&p, 35) // ポインタを渡す
fmt.Println("変更後の年齢:", p.Age)
}
解説:
*Person
型のポインタを受け取る関数changeAge
を定義します。- 関数内で
p.Age = newAge
とすることで、元の構造体の値を直接変更できます。 &p
を渡すことで、ポインタ経由で構造体を操作します。
実行結果:
変更前の年齢: 30 変更後の年齢: 35
構造体にメソッドを定義
Goでは、構造体にメソッドを定義することができます。
package main
import "fmt"
// Person構造体の定義
type Person struct {
Name string
Age int
}
// メソッドの定義(ポインタレシーバ)
func (p *Person) Greet() {
fmt.Printf("こんにちは、私は%sです。%d歳です。\n", p.Name, p.Age)
}
func main() {
p := Person{Name: "次郎", Age: 20}
p.Greet() // メソッドを呼び出し
}
解説:
func (p *Person) Greet()
のように、struct
に関連するメソッドを定義できます。- ポインタレシーバ(
*Person
)を使うことで、オブジェクトのフィールドを変更するメソッドを作成できます。
実行結果:
こんにちは、私は次郎です。20歳です。
構造体の埋め込み(Goの疑似的な継承)
Goには継承はありませんが、構造体の埋め込みを使って親子関係のような構造を作ることができます。
package main
import "fmt"
// 基本構造体
type Person struct {
Name string
Age int
}
// Personを埋め込む新しい構造体
type Employee struct {
Person // 埋め込み
Position string
}
func main() {
e := Employee{
Person: Person{Name: "太郎", Age: 40},
Position: "エンジニア",
}
fmt.Println("名前:", e.Name) // Personのフィールドにもアクセスできる
fmt.Println("年齢:", e.Age)
fmt.Println("職業:", e.Position)
}
解説:
Employee
構造体にPerson
を埋め込むことで、Person
のフィールドに直接アクセスできます。e.Name
やe.Age
のように、埋め込んだ構造体のフィールドを簡単に利用できます。
実行結果:
名前: 太郎 年齢: 40 職業: エンジニア
注意事項
- 構造体は値型: そのまま代入するとコピーが作成されるため、変更を反映する場合はポインタを使う。
- フィールド名は大文字でエクスポート: 他のパッケージからアクセスするには、フィールド名を大文字で始める必要がある。
- 埋め込みは継承ではない: 埋め込みを使うと、フィールドやメソッドを持つことができるが、明示的な親子関係はない。
よくある質問
- Q: 構造体のフィールドを後から追加できますか?
- A: いいえ。Goの構造体は固定サイズのため、動的にフィールドを追加することはできません。
- Q: 構造体のデフォルト値は?
- A: 数値は
0
、文字列は""
、ブーリアンはfalse
、ポインタはnil
になります。 - Q: メソッドでポインタレシーバを使う理由は?
- A: フィールドを変更する場合はポインタレシーバが必要です。値レシーバの場合、コピーが渡されるため変更が反映されません。
- Q: Goにはクラスはないのですか?
- A: はい。Goはオブジェクト指向言語ではなく、クラスの代わりに
struct
を使用します。
まとめ
struct
を使うと、複数のフィールドを持つカスタムデータ型を作成できる。- ポインタを使うと、構造体のフィールドを直接変更できる。
- メソッドを定義することで、構造体に動作を追加できる。
- 埋め込みを使うと、他の構造体を拡張することができる。