首頁  >  文章  >  後端開發  >  為什麼具體類型實作不能滿足 Go 中傳回介面的介面方法?

為什麼具體類型實作不能滿足 Go 中傳回介面的介面方法?

DDD
DDD原創
2024-10-26 22:48:03336瀏覽

Why Doesn't a Concrete Type Implementation Satisfy an Interface Method Returning an Interface in Go?

傳回介面的介面方法與特定型別實作不符

在Go 中,傳回介面的介面方法只符合宣告介面本身的實現,而不是具體的實作實作介面的類型。考慮以下範例:

<code class="go">package main

import "fmt"

type Foo struct {
    val string
}

func (f *Foo) String() string {
    return f.val
}

type StringerGetter interface {
    GetStringer() fmt.Stringer
}

type Bar struct{}

func (b *Bar) GetStringer() *Foo {
    return &Foo{"foo"}
}

func Printer(s StringerGetter) {
    fmt.Println(s.GetStringer())
}

func main() {
    f := Bar{}
    Printer(&f) // compile-time error
}</code>

此程式碼給出以下編譯時錯誤:

cannot use &f (type *Bar) as type StringerGetter in argument to Printer:  *Bar does not implement StringerGetter (wrong type for GetStringer method)

要解決此問題,Bar 類型中的GetStringer 方法應傳回fmt .Stringer 介面而不是具體的*Foo 類型,或者應該修改StringerGetter 介面以接受具體類型而不是介面。

替代解決方案

在修改外部具體類型的情況下或共享介面不理想,有兩種替代解決方案:

  1. 建立包裝類型:您可以建立一個包裝外部具體類型並實現所需的新類型介面。例如:
<code class="go">type MyBar struct {
    Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.Bar.GetStringer()
}</code>
  1. 嵌入特定類型: 或者,您可以將外部具體類型嵌入到您自己的類型中,並使用嵌入類型的介面來實作接口方法。例如:
<code class="go">type MyBar struct {
    embed Bar
}

func (b *MyBar) GetStringer() fmt.Stringer {
    return b.GetStringer()
}</code>

兩種方法都允許您使用外部具體類型,同時提供所需的介面實現,而無需修改原始類型或共用介面。

以上是為什麼具體類型實作不能滿足 Go 中傳回介面的介面方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn