構造体
埋め込み型としての構造体 ( Goは継承を使わない )
Goには継承という概念がない。そのため構造体をうまく利用して埋め込み作業をしていく。
Goでは構造体の中に構造体を埋め込むことで再利用性を高めたり、コード量を減らすことが出来る。
Person型とCitizen型はどちらも独立しており、親子関係にはならない。(is-a関係)
code:main.go
package main
import "fmt"
func main() {
c := Citizen{}
c.Country = "japan"
c.Name = "hoge"
// func(p Person)Greet()string が出力される。
// func(c Citizen)Greet()string を定義した場合はこっちが呼ばれる。
greet := c.Greet() // == c.Person.Greet() ← こうすると型が明白になり分かりやすい。
fmt.Println(greet)
}
type Person struct {
Name string
}
func (p Person) Greet () string {
return "Hello"
}
type Citizen struct {
Country string
// このようにPerson型を埋め込むことでPerson型を受け取るレシーバを扱えるようになる(擬似的部分型)
Person
}
上記の例を違う関数から間接的に呼び出そうとすると失敗する
そのためインターフェースを活用する
code:main.go
//上の続き
func main() {
p := Person{Name:"hoge"}
c := Citizen{
Person{Name:"fuga"},
Country:"japan",
}
Speak(p)
Speak(c)
}
// これは機能しない
// func speak(p Person){
// return Greet(p)
// }
type Human interface {
Greet() string
}
//これは機能する
// Citizen型が Greet()string を実装していなくても通る
func Speak(h Human) {
return Greet(h)
}
参照
/icons/hr.icon
外部パッケージとの依存関係を分離する
外部パッケージを利用するときは他のパッケージに影響が及ばないようにする。
たとえばGinを使うときにGin.New()をそのまま使うのではなく、構造体経由で呼べるようにする。
そうすることで外部パッケージの処理はそのパーケージ内で収まるので管理がしやすくなる。
code:go
type Server struct {
engine *gin.Engine
}
func Start() {
s := NewServer()
s.Router()
s.engine.Run(":8686")
}
/icons/hr.icon