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

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

在 Go 中為多類型數組創建通用函數

在 Go 中為多類型數組創建通用函數

Go
米脂 2022-01-04 09:49:43
我正在嘗試創建一個通用函數,該函數可以處理 Go 中切片上的操作......例如,將任何類型的項目附加到相同類型的切片。這只是一個更復雜的解決方案的通用目的,但總的來說問題歸結為這個例子:package maintype car struct {    make  string    color string}type submarine struct {    name   string    length int}func genericAppender(thingList interface{}, thing interface{}) []interface{} {    return append(thingList, thing)}func main() {    cars := make([]car, 0, 10)    cars[0] = car{make: "ford", color: "red"}    cars[1] = car{make: "chevy", color: "blue"}    subs := make([]submarine, 0, 10)    subs[0] = submarine{name: "sally", length: 100}    subs[1] = submarine{name: "matilda", length: 200}    newCar := car{make: "bmw", color: "white"}    genericAppender(&cars, newCar)}代碼游樂場就在這個位置上述錯誤如下:prog.go:14: first argument to append must be slice; have interface {}
查看完整描述

3 回答

?
www說

TA貢獻1775條經驗 獲得超8個贊

在此更改之后,您仍然會收到運行時錯誤(索引超出范圍),但問題是這thingList不是類型[]interface{},而是interface{}您無法附加到它。這是操場上代碼的更新版本,它執行類型斷言以將其轉換為[]interface{}符合追加的。實際上,您需要在單獨的行上執行此操作并檢查錯誤。


https://play.golang.org/p/YMed0VDZrv


所以在這里放一些代碼;


func genericAppender(thingList interface{}, thing interface{}) []interface{}  {

    return append(thingList.([]interface{}), thing)

}

將解決您面臨的基本問題。如前所述,在對切片進行索引時,您仍然會遇到運行時錯誤。此外,您可以通過更改參數來避免這種情況;


func genericAppender(thingList []interface{}, thing interface{}) []interface{} {

    return append(thingList, thing)

}

這是第二種類型的完整示例;https://play.golang.org/p/dIuW_UG7XY


注意我還更正了運行時錯誤。當您使用帶有 3 個參數的 make 時,它們按此順序是類型、長度、容量。這意味著數組的長度為 0,因此當您嘗試分配索引 0 和 1 時,它會導致 IndexOutoFRange 出現恐慌。相反,我刪除了中間參數,因此這make([]interface{}, 10)意味著長度最初設置為 10,因此您可以分配給這些索引。


查看完整回答
反對 回復 2022-01-04
?
飲歌長嘯

TA貢獻1951條經驗 獲得超3個贊

在上面的答案中,如果您執行以下操作,則會引發錯誤。這就是最初的問題是關于:


//genericAppender(subs, newCar). // Throws "cannot use subs (type []submarine) as type []interface {} in argument to genericAppender"

訣竅是將特定類型的切片轉換為通用 []interface{}。


func convertToGeneric(thingList interface{}) []interface{} {

        input := reflect.ValueOf(thingList)

        length := input.Len()

        out := make([]interface{},length)

        for i:=0 ;i < length; i++ {

           out[i] = input.Index(i).Interface()

        }

    return out

}

你可以這樣調用函數:


genericAppender(convertToGeneric(subs), newCar)

您可以在此處查看修改后的工作代碼:https : //play.golang.org/p/0_Zmme3c8lT


查看完整回答
反對 回復 2022-01-04
?
當年話下

TA貢獻1890條經驗 獲得超9個贊

使用 Go 1.19(2022 年第 4 季度),無需接口,或“將特定類型的切片轉換為泛型[]interface{}”


CL 363434帶有一個新的切片包:


// Package slices defines various functions useful with slices of any type.

// Unless otherwise specified, these functions all apply to the elements

// of a slice at index 0 <= i < len(s).

package slices

import "constraints"


// Grow increases the slice's capacity, if necessary, to guarantee space for

// another n elements. After Grow(n), at least n elements can be appended

// to the slice without another allocation. If n is negative or too large to

// allocate the memory, Grow panics.

func Grow[S ~[]T, T any](s S, n int) S {

    return append(s, make(S, n)...)[:len(s)]

}


// Equal reports whether two slices are equal: the same length and all

// elements equal. If the lengths are different, Equal returns false.

// Otherwise, the elements are compared in index order, and the

// comparison stops at the first unequal pair.

// Floating point NaNs are not considered equal.

func Equal[T comparable](s1, s2 []T) bool {

    if len(s1) != len(s2) {

        return false

    }

    for i, v1 := range s1 {

        v2 := s2[i]

        if v1 != v2 {

            return false

        }

    }

    return true

}


// ...

Ian Lance Taylor在issue 45955 中確認:


這個包現在可以在golang.org/x/exp/slices.

每此線程,它會不會被放入標準庫,直到1.19版本。

我們當然可以根據我們了解的任何內容對其進行調整x/exp。


查看完整回答
反對 回復 2022-01-04
  • 3 回答
  • 0 關注
  • 192 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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