Goにおける構造体の継承の理解
Takashi Yamamoto
Infrastructure Engineer · Leapcell

Key Takeaways
- Goは、クラスベースの継承の代わりに、構造体のコンポジションを使用します。
- 埋め込み構造体は、フィールドとメソッドを外部構造体に昇格させます。
- インターフェースは、明示的な継承を必要とせずにポリモーフィズムを可能にします。
多くのオブジェクト指向プログラミング言語では、継承により、新しいクラスが既存のクラスからプロパティと動作を取得できます。 ただし、Go(Golang)は異なるアプローチを取ります。 従来のクラスベースの継承の代わりに、Goはコンポジションを利用して同様の結果を実現します。 この記事では、Goの構造体コンポジションの仕組みと、それを使用して複雑なデータ構造を構築する方法について説明します。
Goの構造体
Goでは、struct
は、変数を単一の名前でグループ化する複合データ型です。 これらの変数(フィールドと呼ばれます)は、異なる型を持つことができます。 簡単な例を次に示します。
package main import "fmt" type Person struct { Name string Age int } func main() { p := Person{Name: "Alice", Age: 30} fmt.Println(p) }
この例では、Person
は2つのフィールドName
とAge
を持つ構造体です。
継承よりもコンポジション
Goは、継承よりもコンポジションの使用を推奨しています。 階層的なクラス構造を作成する代わりに、Goでは、単純な型を組み合わせて複雑な型を構築できます。 これは、構造体を別の構造体内に埋め込むことによって実現されます。
構造体の埋め込み
構造体が別の構造体内に埋め込まれると、埋め込み構造体のフィールドとメソッドは、外部構造体を通じてアクセスできるようになります。 仕組みは次のとおりです。
package main import "fmt" type Address struct { City, State string } type Person struct { Name string Age int Address // Address構造体の埋め込み } func main() { p := Person{ Name: "Bob", Age: 25, Address: Address{ City: "New York", State: "NY", }, } fmt.Println(p) fmt.Println("City:", p.City) // 埋め込みフィールドへの直接アクセス }
この例では、Person
はAddress
構造体を埋め込んでいます。 これは、Person
がAddress
のフィールドを継承し、Person
インスタンスを通じてCity
およびState
に直接アクセスできることを意味します。
メソッドの昇格
埋め込み構造体で定義されたメソッドは、外部構造体に昇格されます。 これにより、外部構造体は、埋め込み構造体のメソッドをまるで自分のメソッドであるかのようにアクセスできます。
package main import "fmt" type Address struct { City, State string } func (a Address) FullAddress() string { return a.City + ", " + a.State } type Person struct { Name string Age int Address } func main() { p := Person{ Name: "Charlie", Age: 28, Address: Address{ City: "Los Angeles", State: "CA", }, } fmt.Println(p.FullAddress()) // 埋め込み構造体からのメソッドの呼び出し }
ここでは、FullAddress
はAddress
のメソッドですが、埋め込みのためにPerson
で呼び出すことができます。
インターフェースとポリモーフィズム
Goは従来の継承をサポートしていませんが、ポリモーフィズムを可能にする強力なインターフェース機能を提供します。 インターフェースは、型が実装する必要があるメソッドのセットを定義します。 これらのメソッドを実装する型はすべて、インターフェースを満たします。
package main import "fmt" type Describer interface { Describe() string } type Person struct { Name string Age int } func (p Person) Describe() string { return fmt.Sprintf("%s is %d years old.", p.Name, p.Age) } type Product struct { Name string Price float64 } func (p Product) Describe() string { return fmt.Sprintf("%s costs $%.2f.", p.Name, p.Price) } func PrintDescription(d Describer) { fmt.Println(d.Describe()) } func main() { p := Person{Name: "Dave", Age: 22} pr := Product{Name: "Laptop", Price: 999.99} PrintDescription(p) PrintDescription(pr) }
この例では、Person
型とProduct
型の両方がDescribe
メソッドを定義することにより、Describer
インターフェースを実装しています。 PrintDescription
関数は、Describer
インターフェースを満たす任意の型を受け入れ、ポリモーフィズムを示しています。
結論
Goの構造体コンポジションとインターフェースへのアプローチは、従来の継承なしに型を構築および拡張するための柔軟で強力な方法を提供します。 構造体を埋め込み、インターフェースを実装することにより、保守および理解が容易な、複雑で再利用可能なコード構造を作成できます。
FAQs
いいえ、Goはクラスベースの継承ではなく、コンポジションに依存しています。
ある構造体を別の構造体の内部に埋め込むことにより、フィールドとメソッドが外部構造体に昇格されます。
必要なメソッドを実装する型がインターフェースを満たすインターフェースを使用します。
【Leapcellは、Goプロジェクトをホストするための最適な選択肢です。】(https://leapcell.io/)
Leapcellは、Webホスティング、非同期タスク、およびRedis向けの次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ料金を支払います—リクエストも料金もかかりません。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで、平均応答時間60ミリ秒で694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOpsの統合。
- 実用的な洞察のためのリアルタイムメトリクスとロギング。
簡単なスケーラビリティと高性能
- 高い並行性を簡単に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ—構築に集中するだけです。
ドキュメントで詳細をご覧ください!
Xでフォローしてください:@LeapcellHQ