首頁  >  文章  >  後端開發  >  當具體類型實作傳回具體類型而不是介面方法中預期的介面類型時,為什麼 Go 會拋出錯誤?

當具體類型實作傳回具體類型而不是介面方法中預期的介面類型時,為什麼 Go 會拋出錯誤?

DDD
DDD原創
2024-10-30 07:33:02189瀏覽

Why does Go throw an error when a concrete type implementation returns a concrete type instead of the expected interface type in an interface method?

介面方法傳回介面與具體類型實作不符

使用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)
}</code>

這裡, Printer 函數需要一個StringerGetter 接口,該介面有一個傳回fmt.Stringer 的GetStringer 方法,而Bar 類型的GetStringer 方法則傳回一個實作fmt .Stringer 介面的具體類型Foo。這會導致錯誤:

prog.go:29: cannot use &f (type *Bar) as type StringerGetter in
argument to Printer: *Bar does not implement StringerGetter (wrong
type for GetStringer method) had GetStringer() *Foo want
GetStringer() fmt.Stringer

這個問題的解決方案在於使介面的方法與預期的介面類型相符。在這種情況下,GetStringer 方法應該傳回fmt.Stringer 而不是具體類型:

<code class="go">func (b *Bar) GetStringer() fmt.Stringer {
    return &Foo{"foo"}
}</code>

或者,可以建立一個包裝類型來實現所需的介面並委託給具體類型,如以下技術:

型嵌入與委託:

<code class="go">type MyBar struct{ Bar }

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

類型包裝:

<code class="go">type MyBar Bar

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

這些技術允許與具體類型無縫連接,而無需直接修改它們。透過包裝或嵌入具體類型,可以建立符合所需介面契約的自訂類型。

以上是當具體類型實作傳回具體類型而不是介面方法中預期的介面類型時,為什麼 Go 會拋出錯誤?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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