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

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

短變量聲明和“變量已聲明但未使用”錯誤

短變量聲明和“變量已聲明但未使用”錯誤

Go
慕哥6287543 2023-04-04 14:26:34
我偶然發現了一個奇怪的問題,下面的代碼無法編譯:func main() {    var val reflect.Value    var tm time.Time    if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {        panic(err)    }    val = reflect.ValueOf(tm)    fmt.Println(val, tm, reflect.TypeOf(tm))}出現錯誤(代碼是 linter 推薦的代碼):$ go run main.go# command-line-arguments./main.go:13:5: tm declared and not used注意tm變量確實被使用了。但是,如果我添加一個 else 塊 - 一切都按預期編譯:func main() {    var val reflect.Value    var tm time.Time    if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {        panic(err)    } else {        val = reflect.ValueOf(tm)    }    fmt.Println(val, tm, reflect.TypeOf(tm))}這看起來像是編譯器中的錯誤或者可能是已知問題?任何想法?(我正在使用 go 1.11)編輯:到目前為止所有的回應者。根據:https: //golang.org/ref/spec#Short_variable_declarations與常規變量聲明不同,短變量聲明可以重新聲明變量,前提是它們最初是在同一塊(如果塊是函數體,則為參數列表)中較早聲明的,具有相同的類型,并且至少有一個非空變量是新的。因此,重新聲明只能出現在多變量簡短聲明中。重新聲明不會引入新變量;它只是為原始值分配了一個新值。
查看完整描述

2 回答

?
楊魅力

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

這部分:

if tm, err := time.Parse(...)

創建一個僅在語句內具有范圍的變量- 它不是您聲明為的變量。tmifvar tm time.Time

此新變量未在 中使用if,因此會出現錯誤。請注意,您也沒有tm分配外部級別,因此fmt.Println將打印零時間,而不是 time.Parse 返回的時間。

要解決此問題:聲明err并更改if為:

var err errorif tm, err = time.Parse(...)

注意這是 GO 中的一個微妙的事情,也是一個相當常見的錯誤來源。該:=語句實際上可以與已經聲明的變量和一個或多個變量的混合使用 - 如果已經聲明的變量在相同的詞法范圍內。然后,只有新的由自動聲明:=,其余的只是分配(與=)。但是,如果您在新范圍內使用:=,則所有變量都在該范圍內聲明,并屏蔽任何具有相同名稱的外部范圍變量(例如在 ;if注意條件if不在大括號內,但仍被視為如果它在塊內; GO 中的{code}the 和其他復合語句也會發生同樣的情況)。for


查看完整回答
反對 回復 2023-04-04
?
溫溫醬

TA貢獻1752條經驗 獲得超4個贊

您的if語句聲明了一個新變量tm,該變量僅存在于if塊的范圍內并且確實從未使用過:

if?tm,?err?:=?time.Parse(time.RFC3339,?"2018-09-11T17:50:54.247Z");?err?!=?nil?{
????panic(err)
}

在 Go 中,:=聲明一個變量并對其進行初始化。你的意思可能是:

func main() {

? ? var val reflect.Value

? ? var tm time.Time

? ? var err error


? ? // Note the change to normal assignment here instead of :=

? ? if tm, err = time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {

? ? ? ? panic(err)

? ? }

? ? val = reflect.ValueOf(tm)


? ? fmt.Println(val, tm, reflect.TypeOf(tm))

}

shortcut運算符在Go Tour of Go:=中進行了演示,并在Go spec中進行了解釋,后者包括:

它是帶有初始化表達式但沒有類型的常規變量聲明的簡寫:

"var" IdentifierList = ExpressionList .

Go 規范中也解釋了作用域。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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