亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在接口約束中定義結構字段(類型 T 沒有字段或方法)?

如何在接口約束中定義結構字段(類型 T 沒有字段或方法)?

Go
慕田峪4524236 2022-10-17 19:33:53
我想讓下面的代碼編譯。我從閱讀 Type Parameters Proposal (Go Generics) 的理解是這應該可行,但我必須遺漏一些東西。package mainimport "fmt"func main() {    s := Struct{A: "Hello World!"}    PrintA(s)}func PrintA[T Type](v T) {    fmt.Printf("%s\n", v.A)}type Type interface {    struct{ A string }}type Struct struct {    A string}func (s Struct) String() string {    return s.A}我得到的錯誤是:./prog.go:7:8: Struct 沒有實現 Type (可能缺少 ~ for struct{A string} in constraint Type) ./prog.go:11:23: vA undefined (interface Type沒有方法A)我想T用特定類型的特定字段表示所有結構。添加~沒有幫助。這是提案中的一個示例,該示例已實施并且是最新的 Go beta 版本的一部分。type structField interface {    struct { a int; x int } |        struct { b int; x float64 } |        struct { c int; x uint64 }}https://go.dev/play/p/KZh2swZuD2m?v=gotip
查看完整描述

1 回答

?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

Go 1.18 已完全禁用字段訪問。Go 1.18 發行說明提到了這一點:


當前的泛型實現具有以下已知限制:


[...]


Go 編譯器不支持訪問類型參數 type的結構字段x.f,即使類型參數的類型集中的所有類型都有一個 field。我們可能會在 Go 1.19 中刪除此限制。xf

任何 struct 類型的解決方法都歸結為舊的無聊的基于接口的多態性,到目前為止我們都在使用,沒有類型參數:


type Type interface {

    GetA() string

}


func (s Struct) GetA() string {

    return s.A

}

在這一點上,您甚至不必將Type接口用作約束。它可以只是一個普通的接口類型:


func PrintA(v Type) {

    fmt.Printf("%s\n", v.GetA())

}

舊答案


在 2022 年初的某個時候,此功能仍在開發中,如果您添加以下內容,您的示例確實有效~:


type Type interface {

    ~struct{ A string }

}

但它只適用于完全定義為的結構struct{ A string },沒有別的。定義一個約束“表示[s]所有具有特定類型的特定字段的結構”一直以來都不受支持。有關詳細信息,請參閱此答案。


相反,您從提案中引用的示例是關于訪問類型集中的公共字段。通過定義結構的聯合:


type structField interface {

    ~struct { a int; x int } | ~struct { a int; x float64 } 

}

您應該能夠訪問a此類類型參數的字段,但是正如答案開頭所述,這又沒有實現。如果聯合中的所有術語都具有相同的基礎類型,它曾經可以工作(示例改編自問題 #48522):


package main


import "fmt"


type Point struct {

    X, Y int

}


type Rect struct {

    X, Y int

}


func GetX[P Point | Rect] (p P) int {

    return p.X

}


func main() {

    p := Point{1, 2}

    r := Rect{2, 3}

    fmt.Println("X: %d %d", GetX(p), GetX(r)) // prints X: 1 2

}

自 2022 年 3 月起,此代碼不再編譯。


查看完整回答
反對 回復 2022-10-17
  • 1 回答
  • 0 關注
  • 128 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號