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

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

使用泛型:type *T 是指向類型參數的指針,而不是類型參數

使用泛型:type *T 是指向類型參數的指針,而不是類型參數

Go
撒科打諢 2022-11-23 10:25:19
可能是 golang 初學者的問題:)嘗試編譯下面的代碼時,我遇到了以下編譯器錯誤。我想為共享公共 ID 字段的不同類型(這里是 A 和 B)實現一個對象存儲。按照 DRY 的想法,我想使用泛型來實現商店。添加一個對象時,我想使用GS接口設置它的ID字段(當然實際代碼要復雜一些),但是編譯器不希望我這樣做。./prog.go:29:7: item.SetId 未定義(type *T 是指向類型參數的指針,而不是類型參數)./prog.go:34:24: A沒有實現GS(SetId方法有指針接收者)有推薦的方法來解決這個問題嗎?提前致謝?。ackage mainimport "fmt"type A struct {    ID      string    AMember string}type B struct {    ID      string    BMember string}type GS interface {    Id() string    SetId(string)}func (s A) Id() string      { return s.ID }func (s *A) SetId(i string) { s.ID = i }func (s B) Id() string      { return s.ID }func (s *B) SetId(i string) { s.ID = i }type MyStore[T GS] struct {    values map[string]*T}func (s *MyStore[T]) add(item *T) {    item.SetId("aa")    s.values["aa"] = item}func main() {    var storeA = &MyStore[A]{}    storeA.values = make(map[string]*A)    a := &A{}    storeA.add(a)    fmt.Println(a.Id())}
查看完整描述

1 回答

?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

關于使用 *T

簡而言之,類型參數不是它的約束。該約束僅確定 上可用的操作T,它并不暗示關于 的任何內容*T,它現在只是一個未命名的指針類型。這是意義:

type *T 是指向類型參數的指針,而不是類型參數

因此,與您的情況一樣,方法集*T不會自動包含在T具體類型上聲明的指針接收器方法A,并且它不會實現將由 實現的接口*A。

您必須通過設置額外的約束將其明確告知編譯器。在簡化形式中,它類似于:

func Foo[T any, PT interface { SetId(string); *T}](v T) {}

您可以在此處找到有關此用例的更多示例和變體:

關于實施約束

&MyStore[A]{}錯誤消息清楚地報告了此實例化失敗的原因:

A沒有實現GS(SetId方法有指針接收者)

換句話說SetId(),聲明于*A,而不是A。因此你應該實例MyStore*A

var storeA = &MyStore[*A]{}

然后*T將結構/方法定義中的出現更改為T

type MyStore[T GS] struct {
    values map[string]T // just T instead of *T
    }
    func (s *MyStore[T]) add(item T) {
}

在使用字段類型實例化時,*A將變得等效于map[string]*A因此使分配storeA.values = make(map[string]*A)有效,并且方法簽名add(item *A)因此允許storeA.add(&A{}).

固定游樂場:https ://gotipplay.golang.org/p/dcUVJ5YQK_b


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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