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

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

在恒等函數中將類型 T 轉換為類型 U

在恒等函數中將類型 T 轉換為類型 U

Go
絕地無雙 2023-03-15 14:22:39
使用下面給定的類型簽名,有沒有辦法做類似于下面的事情?func Transform[T, U any](item T) U {    return item}上面的代碼給出了以下錯誤:cannot use item (variable of type T constrained by any) as U value in return statement我無法使用上面的類型簽名,因為我本質上是在嘗試制作一個可選的轉換方法,有時需要從 T 轉換為 U,但有時只返回自身。下面顯示了一個更詳細的用例示例。type SomeStruct[T, U any] struct {    Transform func(T) U}func (s SomeStruct[T, U]) Transform(elem T) (U) {    if s.Transform != nil {        return s.Transform(elem)    }    return elem}有沒有辦法創建一個有時有條件地只返回自身的 Transform 函數?
查看完整描述

2 回答

?
阿波羅的戰車

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

您可以使您的代碼片段工作:


func Transform[T, U any](item T) U {

    return any(item).(U)

}

但是如果與 的實際類型不斷言兼容,代碼將因恐慌而失敗:Uitem


這會恐慌:


fmt.Println(Transform[string, int]("foo"))


// Output: panic: interface conversion: interface {} is string, not int

這在沒有恐慌的情況下成功了,因為bytes.Buffer它同時實現了io.Reader和io.Writer接口:


b := &bytes.Buffer{}

_ = Transform[io.Writer, io.Reader](b)

所以,可以做你想做的事。但我不確定它有多大用處,因為實際參數運行時失敗與U.


查看完整回答
反對 回復 2023-03-15
?
心有法竹

TA貢獻1866條經驗 獲得超5個贊

T如果您的函數定義為 return ,則無法返回U。即使您斷言Tto U,該函數仍會返回U。


如果你真的想返回or T,U你需要將返回類型聲明為any:


func (s SomeStruct[T, U]) Transform(elem T) any { /* ... */ }

...放棄靜態類型;或者您可以使用“任一”類型的助手:


type Either[T, U any] struct {

    value any

}


// Either methods


func (s SomeStruct[T, U]) Transform(elem T) Either[T, U] {

    if s.transform == nil {

        return Either[T, U]{elem}

    }

    return Either[T, U]{s.transform(elem)}

}

看看如何在這個 playground中使用它。


備選方案將偏離您的既定目標。一種是實際斷言Tto U,但您必須知道這會返回U,而不是T,即使T它的值可分配給U:


func (s SomeStruct[T, U]) Transform(elem T) U {

    if s.transform == nil {

        if u, ok := any(elem).(U); ok {

            return u

        }

        return *new(U) // U's zero value if elem assertion fails

    }

    return s.transform(elem)

}

您必須使用斷言,因為類型參數T和U都受 約束any,因此(理所當然地)沒有其他方式來表達兩者之間的可轉換性。comma-ok 習慣用法有助于避免運行時恐慌。


或者您可以返回(U, error),這通常是合理的做法:


func (s SomeStruct[T, U]) Transform(elem T) (u U, err error) {

    if s.transform == nil {

        err = errors.New("transform function not set")

        return 

    }

    u = s.transform(elem)

    return

}

游樂場:https://go.dev/play/p/GKLRmKKWxlP


查看完整回答
反對 回復 2023-03-15
  • 2 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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