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

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

golang返回多個(gè)值問題

golang返回多個(gè)值問題

Go
阿晨1998 2021-10-04 16:38:26
我想知道為什么這是有效的 go 代碼:func FindUserInfo(id string) (Info, bool) {    it, present := all[id]    return it, present}但這不是func FindUserInfo(id string) (Info, bool) {    return all[id]}有沒有辦法避免臨時(shí)變量?
查看完整描述

5 回答

?
小唯快跑啊

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

為了詳細(xì)說明我的評(píng)論,Effective Go提到訪問映射鍵的多值分配稱為“逗號(hào)確定”模式。


有時(shí)您需要將缺失的條目與零值區(qū)分開來。是否有“UTC”條目,或者是空字符串,因?yàn)樗静辉诘貓D中?你可以用多重賦值的形式來區(qū)分。


var seconds int

var ok bool

seconds, ok = timeZone[tz]

出于顯而易見的原因,這被稱為“逗號(hào)確定”習(xí)語(yǔ)。在這個(gè)例子中,如果 tz 存在,秒將被適當(dāng)?shù)卦O(shè)置并且 ok 為真;如果沒有,秒將被設(shè)置為零,確定將是假的。


操場(chǎng)證明這個(gè)


我們可以看到這與調(diào)用常規(guī)函數(shù)不同,在常規(guī)函數(shù)中編譯器會(huì)告訴您出現(xiàn)問題:


package main


import "fmt"


func multiValueReturn() (int, int) {

    return 0, 0

}


func main() {

    fmt.Println(multiValueReturn)


    asgn1, _ := multiValueReturn()


    asgn2 := multiValueReturn()

}

在操場(chǎng)上,這將輸出


# command-line-arguments

/tmp/sandbox592492597/main.go:14: multiple-value multiValueReturn() in single-value context

這給了我們一個(gè)提示,它可能是編譯器正在做的事情。搜索“commaOk”的源代碼為我們提供了幾個(gè)可以查看的地方,包括types.unpack


在撰寫本文時(shí),該方法的 godoc 內(nèi)容如下:


// unpack takes a getter get and a number of operands n. If n == 1, unpack

// calls the incoming getter for the first operand. If that operand is

// invalid, unpack returns (nil, 0, false). Otherwise, if that operand is a

// function call, or a comma-ok expression and allowCommaOk is set, the result

// is a new getter and operand count providing access to the function results,

// or comma-ok values, respectively. The third result value reports if it

// is indeed the comma-ok case. In all other cases, the incoming getter and

// operand count are returned unchanged, and the third result value is false.

//

// In other words, if there's exactly one operand that - after type-checking

// by calling get - stands for multiple operands, the resulting getter provides

// access to those operands instead.

//

// If the returned getter is called at most once for a given operand index i

// (including i == 0), that operand is guaranteed to cause only one call of

// the incoming getter with that i.

//

其關(guān)鍵在于此方法似乎可以確定某事是否實(shí)際上是“逗號(hào)正?!鼻闆r。


挖掘到這個(gè)方法告訴我們,它會(huì)檢查,看是否操作數(shù)的模式索引地圖或者模式設(shè)置為commaok(其中這個(gè)定義確實(shí)給我們當(dāng)?shù)挠盟谠S多提示,但搜索任務(wù)源到commaok我們可以看到它時(shí)所使用的正從一個(gè)信道的值和類型的斷言)。記住加粗的部分以備后用!


if x0.mode == mapindex || x0.mode == commaok {

    // comma-ok value

    if allowCommaOk {

        a := [2]Type{x0.typ, Typ[UntypedBool]}

        return func(x *operand, i int) {

            x.mode = value

            x.expr = x0.expr

            x.typ = a[i]

        }, 2, true

    }

    x0.mode = value

}

allowCommaOk是函數(shù)的參數(shù)。查看unpack在該文件中調(diào)用的位置,我們可以看到所有調(diào)用者都false作為參數(shù)傳遞。搜索庫(kù)的其余部分使我們assignments.go的Checker.initVars()方法。


l := len(lhs)

get, r, commaOk := unpack(func(x *operand, i int) { check.expr(x, rhs[i]) }, len(rhs), l == 2 && !returnPos.IsValid())

由于在執(zhí)行多值賦值時(shí)我們似乎只能使用“逗號(hào)確定”模式來獲取兩個(gè)返回值,因此這似乎是正確的地方!在上面的代碼中,檢查了左邊的長(zhǎng)度,當(dāng)unpack被調(diào)用時(shí),allowCommaOk參數(shù)是l == 2 && !returnPos.IsValid(). 將!returnPos.IsValid()在一定程度上混淆這里作為這將意味著,位置沒有相關(guān)的文件或行信息與它,但我們會(huì)就忽略這個(gè)問題。


在該方法中,我們有:


var x operand

if commaOk {

    var a [2]Type

    for i := range a {

        get(&x, i)

        a[i] = check.initVar(lhs[i], &x, returnPos.IsValid())

    }

    check.recordCommaOkTypes(rhs[0], a)

    return

}

那么這一切告訴我們什么呢?


由于該unpack方法allowCommaOk在除inassignment.go的Checker.initVars()方法之外的任何地方都采用硬編碼為 false的參數(shù),我們可以假設(shè)您在進(jìn)行賦值時(shí)只會(huì)得到兩個(gè)值,并且在左側(cè)有兩個(gè)變量。

該unpack方法將通過檢查您是否正在索引切片、從通道中獲取值或進(jìn)行類型斷言來確定您是否確實(shí)獲得了ok返回值

由于您只能ok在進(jìn)行賦值時(shí)獲取值,因此在您的特定情況下,您將始終需要使用變量


查看完整回答
反對(duì) 回復(fù) 2021-10-04
?
胡子哥哥

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

您可以使用命名返回來保存幾個(gè)擊鍵:


func FindUserInfo(id string) (i Info, ok bool) {

    i, ok = all[id]

    return

}

但除此之外,我不認(rèn)為你想要的是可能的。


查看完整回答
反對(duì) 回復(fù) 2021-10-04
?
白衣染霜花

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

簡(jiǎn)單地說:你的第二個(gè)例子不是有效的 Go 代碼的原因是因?yàn)檎Z(yǔ)言規(guī)范是這樣說的。;)

索引映射只會(huì)在兩個(gè)變量的賦值中產(chǎn)生一個(gè)次要值。Return 語(yǔ)句不是賦值語(yǔ)句。

在特殊形式的賦值或初始化中使用的類型為 map[K]V 的映射 a 上的索引表達(dá)式

v, ok = a[x]
v, ok := a[x]
var v, ok = a[x]

產(chǎn)生一個(gè)額外的無類型布爾值。如果鍵 x 存在于映射中,則 ok 的值為真,否則為假。

此外,索引映射不是“對(duì)多值函數(shù)的單一調(diào)用”,它是從函數(shù)返回值的三種方法之一(第二種方法,其他兩種在這里不相關(guān)):

有三種方法可以從具有結(jié)果類型的函數(shù)返回值:

  1. 返回值可以在“return”語(yǔ)句中明確列出。每個(gè)表達(dá)式必須是單值的并且可以分配給函數(shù)結(jié)果類型的相應(yīng)元素。

  2. “return”語(yǔ)句中的表達(dá)式列表可能是對(duì)多值函數(shù)的單個(gè)調(diào)用。效果就好像從該函數(shù)返回的每個(gè)值都被分配給一個(gè)具有相應(yīng)值類型的臨時(shí)變量,然后是一個(gè)列出這些變量的“返回”語(yǔ)句,此時(shí)適用前一種情況的規(guī)則。

  3. 如果函數(shù)的結(jié)果類型為其結(jié)果參數(shù)指定名稱,則表達(dá)式列表可能為空。結(jié)果參數(shù)作為普通的局部變量,函數(shù)可以根據(jù)需要為它們賦值。“return”語(yǔ)句返回這些變量的值。

至于您的實(shí)際問題:避免臨時(shí)變量的唯一方法是使用非臨時(shí)變量,但這通常是非常不明智的 - 即使在安全的情況下也可能沒有太多優(yōu)化。

那么,為什么語(yǔ)言規(guī)范不允許在 return 語(yǔ)句中使用這種特殊的映射索引(或類型斷言或通道接收,兩者都可以使用“逗號(hào)確定”習(xí)語(yǔ))?這是個(gè)好問題。我的猜測(cè):保持語(yǔ)言規(guī)范簡(jiǎn)單。


查看完整回答
反對(duì) 回復(fù) 2021-10-04
  • 5 回答
  • 0 關(guān)注
  • 521 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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