🦔
Go における「継承的」機能:構造体の埋め込み(備忘録)
はじめに
Go には継承という概念がないものの、類似の機能は存在し、ORM ライブラリの中でも利用されています。
この実装は以前から存在したものの、GORM のリファレンスを読んで見かけたこと、実際に使ってみて思ったより便利だったことから、備忘録的に残します。
GORM での実装例
GORM では、よくあるベースモデルとしてgorm.Model
が提供されています。
// gorm.Model definition type Model struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` }
このモデルを自作のモデルに埋め込むことで、楽ができます。
type User struct { gorm.Model Name string }
これが GORM で提供されているEmbedded Struct
になります。
この Go に存在する構造体の埋め込みを利用して継承的なことをやってみます。
実装例:baseModel と Book
今回は、ベースとなるモデル、baseModel
とBook
モデルを使って実装してみます。
以下実装例です。
main.go
package main
import (
"fmt"
"time"
)
type baseModel struct {
ID string
CreatedAt time.Time
}
func (b *baseModel) create() {
b.CreatedAt = time.Now()
fmt.Printf("Base model created with ID: %s at %v\n", b.ID, b.CreatedAt)
}
type Book struct {
baseModel // 構造体の埋め込み
Title string
}
func (b *Book) displayInfo() {
fmt.Printf("Book: %s (ID: %s, Created: %v)\n", b.Title, b.ID, b.CreatedAt)
}
func main() {
book := &Book{
baseModel: baseModel{ID: "1"},
Title: "Go Programming",
}
// baseModelのメソッドを呼び出し
book.create()
// Bookのメソッドを呼び出し
book.displayInfo()
}
こんな感じで、オブジェクト指向っぽいことができます。便利!
構造体埋め込みの注意点
構造体埋め込みには少し注意点があります。
Go の仕様的な話で、異なるpackage
間で使う場合、埋め込んだ構造体のメソッドや値が他の言語のような雰囲気で簡単には利用できないので、要注意です。
参考文献
Discussion