第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在不參考其類型的情況下分配空切片?

在不參考其類型的情況下分配空切片?

Go
紅糖糍粑 2023-01-03 11:29:09
我的代碼調(diào)用了一個(gè)大致如下所示的庫函數(shù):func Search() ([]myLibrary.SomeObject, error) {    var results []apiv17.SomeObject    // ...    if (resultsFound) {      results = append(results, someResult)    }    return results}...我的代碼調(diào)用它,然后將其編組為 JSON。results, err := myLibrary.Search()bytes, err := json.Marshal(results)現(xiàn)在的問題是,由于Search函數(shù)的編寫方式(假設(shè)我們無法更改它),nil如果沒有結(jié)果,它將返回一個(gè)未初始化的切片。不幸的是,沒有辦法配置encoding/json為將 nil 切片編碼為(例如,請(qǐng)參閱正在進(jìn)行的討論中的[]此提案)。明確檢查nil解決問題:results, err := myLibrary.Search()if results == nil {  results = []apiv17.SomeObject{}}bytes, err := json.Marshal(results)...但它也增加了對(duì)返回類型的顯式依賴,apiv17.SomeObject. 這很不方便,因?yàn)樵擃愋驮趲熘薪?jīng)常更改。例如,在下一個(gè)庫版本中它可能是apiv18.SomeObject.通過nil上面的檢查,每次發(fā)生這種情況時(shí)我都必須更新我的代碼。有什么辦法可以避免這種情況,并在不顯式引用其類型的情況下為變量分配一個(gè)空的、非零的切片?是這樣的:results = [](type of results){}
查看完整描述

2 回答

?
POPMUISE

TA貢獻(xiàn)1765條經(jīng)驗(yàn) 獲得超5個(gè)贊

去 1.18

您可以使用通用函數(shù)來捕獲切片的基本類型并返回長(zhǎng)度為零的切片:


func echo[T any](v []T) []T {

    return make([]T, 0)

}


func main() {

    n := foo.GetFooBar()

    if n == nil {

        n = echo(n) // no need to refer to apiv17 here

    }

    bytes, _ := json.Marshal(n)

    fmt.Println(string(bytes)) // prints []

}

需要常規(guī)參數(shù)v []Tin的目的echo是允許類型推斷將切片[]apiv17.SomeObject與參數(shù)統(tǒng)一[]T并推斷T為基本類型apiv17.SomeObject,這樣您就可以調(diào)用它,echo(n)而無需顯式類型參數(shù)。


該包apiv17當(dāng)然在編譯時(shí)是已知的,因?yàn)樗峭ㄟ^ 傳遞導(dǎo)入的myPackage,因此您可以利用這一點(diǎn)和類型推斷來避免為 . 添加顯式import語句apiv17。


這就是它在多文件游樂場(chǎng)上的樣子:https ://go.dev/play/p/4ycTkaGLFpo


該類型在bar包中聲明,但main僅導(dǎo)入play.ground/foo且僅使用foo.GetFooBar.


轉(zhuǎn)到 1.17 及以下版本

反射。只需將echo上面的函數(shù)更改為接受interface{}參數(shù)(anyGo 1.17 中沒有,還記得嗎?),然后執(zhí)行以下操作reflect.MakeSlice:


func set(v interface{}) {

    rv := reflect.ValueOf(v)

    if rv.Kind() != reflect.Ptr {

        panic("not a ptr")

    }

    reflect.Indirect(rv).Set(reflect.MakeSlice(rv.Type().Elem(), 0, 0))

}

然后傳遞一個(gè)指向切片的指針,這樣你就可以用反射來設(shè)置它的值。


func main() {

    n := foo.GetFooBar()

    if n == nil {

        set(&n)

    }

    fmt.Printf("type: %T, val: %v, is nil: %t\n", n, n, n == nil)

    // type: []bar.FooBar, val: [], is nil: false

    

    bytes, _ := json.Marshal(n)

    fmt.Println(string(bytes)) // prints [] again

}

Go 1.17 游樂場(chǎng):https ://go.dev/play/p/4jMkr22LMF7?v=goprev


查看完整回答
反對(duì) 回復(fù) 2023-01-03
?
慕斯王

TA貢獻(xiàn)1864條經(jīng)驗(yàn) 獲得超2個(gè)贊

另一個(gè)答案描述了如何創(chuàng)建一個(gè)空切片。


但是你可以更簡(jiǎn)單地解決你原來的問題:如果results是nil,你不需要?jiǎng)?chuàng)建一個(gè)空切片,不管它有什么元素類型,[]無論如何 JSON 封送處理都是。因此,如果results是nil,則無需調(diào)用json.Marshal(),只需“輸出”即可[]:


results, err := myLibrary.Search()

var bytes []byte

if results == nil {

    bytes = []byte{'[', ']' } // JSON marshaling result is "[]"

} else {

    bytes, err = json.Marshal(results)

    // Handle error

}


查看完整回答
反對(duì) 回復(fù) 2023-01-03
  • 2 回答
  • 0 關(guān)注
  • 105 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)