組成和嵌入

組合提供了繼承的替代方法。結構可以在其宣告中按名稱包含另一種型別:

type Request struct {
    Resource string
}

type AuthenticatedRequest struct {
    Request
    Username, Password string
}

在上面的例子中,AuthenticatedRequest 將包含四個公共成員:ResourceRequestUsernamePassword

可以例項化複合結構,並使用與普通結構相同的方式:

func main() {
    ar := new(AuthenticatedRequest)
    ar.Resource = "example.com/request"
    ar.Username = "bob"
    ar.Password = "P@ssw0rd"
    fmt.Printf("%#v", ar)
}

在操場上玩

嵌入

在前面的示例中,Request 是嵌入欄位。也可以通過嵌入不同型別來實現組合。例如,這可用於裝飾具有更多功能的 Struct。例如,繼續使用 Resource 示例,我們需要一個格式化 Resource 欄位內容的函式,用 http://https://作為字首。我們有兩個選擇:在 AuthenticatedRequest 上建立新方法或從不同的結構中嵌入它:

type ResourceFormatter struct {}

func(r *ResourceFormatter) FormatHTTP(resource string) string {
    return fmt.Sprintf("http://%s", resource)
}
func(r *ResourceFormatter) FormatHTTPS(resource string) string {
    return fmt.Sprintf("https://%s", resource)
}

type AuthenticatedRequest struct {
    Request
    Username, Password string
    ResourceFormatter
}

現在主要功能可以執行以下操作:

func main() {
    ar := new(AuthenticatedRequest)
    ar.Resource = "www.example.com/request"
    ar.Username = "bob"
    ar.Password = "P@ssw0rd"

    println(ar.FormatHTTP(ar.Resource))
    println(ar.FormatHTTPS(ar.Resource))

    fmt.Printf("%#v", ar)
}

看看 AuthenticatedRequest 有一個 ResourceFormatter 嵌入式結構。

它的缺點是你不能訪問你作文之外的物件。所以 ResourceFormatter 無法訪問 AuthenticatedRequest 的成員。

在操場上玩