日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

php小編西瓜將為您介紹如何在Go語言中使用泛型實例化類型參數(shù)的非零指針。在Go語言中,泛型是一種強大的特性,可以增加代碼的靈活性和重用性。當我們需要在泛型函數(shù)或方法中實例化一個非零指針時,可以使用類型斷言和反射來實現(xiàn)。通過使用這些技術,我們可以在運行時根據(jù)類型參數(shù)的具體類型來創(chuàng)建一個非零指針實例,從而實現(xiàn)泛型的靈活性和通用性。下面我們來詳細了解一下具體的實現(xiàn)方法。

問題內容

現(xiàn)在 golang/go:master 上提供了類型參數(shù),我決定嘗試一下。看來我遇到了在類型參數(shù)提案中找不到的限制。 (或者我一定錯過了)。

我想編寫一個函數(shù),它返回帶有接口類型約束的泛型類型值的切片。如果傳遞的類型是帶有指針接收器的實現(xiàn),我們如何實例化它?

type SetGetter[V any] interface {
    Set(V)
    Get() V
}

// SetGetterSlice turns a slice of type V into a slice of type T,
// with T.Set() called for each entry in values.
func SetGetterSlice[V any, T SetGetter[V]](values []V) []T {
    out := make([]T, len(values))

    for i, v := range values {
        out[i].Set(v) // panic if T has pointer receiver!
    }

    return out
}

登錄后復制

當使用 *Count 類型作為 T 調用上述 SetGetterSlice() 函數(shù)時,此代碼將在調用 Set(v) 時出現(xiàn)混亂。 (Go2go 游樂場)毫不奇怪,因為基本上代碼創(chuàng)建了 nil 指針的切片:

// Count implements SetGetter interface
type Count struct {
    x int
}

func (c *Count) Set(x int) { c.x = x }
func (c *Count) Get() int  { return c.x }

func main() {
    ints := []int{1, 2, 3, 4, 5}

    sgs := SetGetterSlice[int, *Count](ints)
    
    for _, s := range sgs {
        fmt.Println(s.Get())
    }
}

登錄后復制

同一問題的變體

這個想法行不通,我似乎找不到任何簡單的方法來實例化指向的值。

    out[i] = new(T) 將導致編譯失敗,因為它返回 *T,其中類型檢查器希望查看 T
    調用 *new(T) 進行編譯,但會導致相同的運行時恐慌,因為 new(T) 返回 **Count 在這種情況下,其中指向 Count 的指針仍然是 nil
    將返回類型更改為指向 T 的指針片段將導致編譯失敗:
func SetGetterSlice[V any, T SetGetter[V]](values []V) []*T {
    out := make([]*T, len(values))

    for i, v := range values {
        out[i] = new(T)
        out[i].Set(v) // panic if T has pointer receiver
    }

    return out
}

func main() {
    ints := []int{1, 2, 3, 4, 5}

    SetGetterSlice[int, Count](ints)
    // Count does not satisfy SetGetter[V]: wrong method signature
}

登錄后復制

解決方法

到目前為止我發(fā)現(xiàn)的唯一解決方案是要求將構造函數(shù)傳遞給泛型函數(shù)。但這感覺不對,而且有點乏味。如果 func F(T interface{})() []T 是完全有效的語法,為什么需要這樣做?

func SetGetterSlice[V any, T SetGetter[V]](values []V, constructor func() T) []T {
    out := make([]T, len(values))

    for i, v := range values {
        out[i] = constructor()
        out[i].Set(v)
    }

    return out
}

// ...
func main() {
    ints := []int{1, 2, 3, 4, 5}

    SetGetterSlice[int, *Count](ints, func() *Count { return new(Count) })
}

登錄后復制

摘要

我的問題(按優(yōu)先順序排列):

    我是否忽略了一些顯而易見的事情?
    這是 Go 中泛型的限制嗎?這已經(jīng)是最好的了嗎?
    此限制是否已知,或者我應該在 Go 項目中提出問題嗎?

解決方法

基本上,您必須向約束添加一個類型參數(shù),以使 T 可轉換為其指針類型。在最基本的形式中,該技術如下所示(帶有匿名約束):

func Foo[T any, PT interface { *T; M() }]() {
    p := PT(new(T))
    p.M() // calling method on non-nil pointer
}

登錄后復制

游樂場:https://www.php.cn/link/24aef8cb3281a2422a59b51659f1ad2e

分步解決方案

您的約束 SetGetter 已經(jīng)聲明了類型參數(shù) V,因此我們稍微修改上面的示例:

// V is your original type param
// T is the additional helper param
type SetGetter[V any, T any] interface {
    Set(V)
    Get() V
    *T
}

登錄后復制

然后定義 SetGetterSlice 函數(shù),其類型參數(shù)為 T any,其目的只是實例化約束 SetGetter

然后您就可以將表達式 &out[i] 轉換為指針類型,并成功調用指針接收器上的方法:

// T is the type with methods with pointer receiver
// PT is the SetGetter constraint with *T
func SetGetterSlice[V any, T any, PT SetGetter[V, T]](values []V) []T {
    out := make([]T, len(values))

    for i, v := range values {
        // out[i] has type T
        // &out[i] has type *T
        // PT constraint includes *T
        p := PT(&out[i]) // valid conversion!
        p.Set(v)         // calling with non-nil pointer receiver
    }

    return out
}

登錄后復制

完整程序:

CFE57E536C89530D9A8C38E10967A10D

這變得更加冗長,因為 SetGetterSlice 現(xiàn)在需要三個類型參數(shù):原始 V 加上 T (帶有指針接收器的類型)和 PT (新約束)。然而,當您調用該函數(shù)時,您可以省略第三個 – 通過類型推斷,實例化 PT SetGetter[V,T] 所需的類型參數(shù) VT 都是已知的:

SetGetterSlice[int, Count](ints)

登錄后復制

游樂場:https://www.php.cn/link/6b061fc28f7473418a006dfa832708b1

分享到:
標簽:Go語言 排列
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定