假設一個函式如:
func returnNamedSlice(num int) (s []int)
我可以直接在代碼中執行以下操作,就好像 s 已經制作了一樣。
s = append(s, 5)
但是如果我不做上面的(append操作),那么s總是nil,回傳s的也是nil。
為什么要這樣設計?這似乎非常不一致。
uj5u.com熱心網友回復:
命名的回傳切片被初始化為 nil。以下陳述句有效,因為函式處理 nil 切片與處理空切片相同append。
s = append(s, 5)
Nil slice 的處理方式與空 slice 相同,因為 nil slice 的長度和容量被定義為零,與空 slice 相同。
該功能與命名的回傳值無關。這是一個沒有回傳值的演示:
var x []int // x is a nil slice of int
fmt.Println(x) // prints []
fmt.Println(x == nil) // prints true
x = append(x, 5) // x is slice with one element, 5
fmt.Println(x) // prints [5]
fmt.Println(x == nil) // prints false
在檢查這些特性時,一個令人困惑的地方是,該fmt包以相同的表示形式列印 nil 切片和空切片,[].
uj5u.com熱心網友回復:
您也可以將專案附加到 nil 切片,無論它是否為 nil。
看下面的例子:
package main
import "log"
func main() {
a := a() // no matter it returns nil
log.Println("Is a nil: ", a == nil)
a = append(a, 1) // you can append items to nil slice
log.Println(a)
//
b := b()
b = append(b, 2)
log.Println(b)
}
func a() (s []int) {
return
}
func b() (s []int) {
s = append(s, 5)
return
}
結果:
2022/06/19 09:52:02 Is a nil: true
2022/06/19 09:52:02 [1]
2022/06/19 09:52:02 [5 2]
uj5u.com熱心網友回復:
Go 中的任何命名回傳變數(“結果引數”,如規范所稱)都“預初始化”為適當的零值,與任何沒有初始化器的本地定義變數完全相同:
var i int
var f float64
var s string
i為零(整數),f為零(0.0,float64),并且s為“零”(空字串"")。所以它與你的功能有關:
func returnNamedSlice(num int) (s []int) {
// ... code here ...
return
}
// code here在代碼所在的函式頂部,s初始化為“零”,即[]int(nil):nil轉換為[]int. 這在 Go 規范的Return statements部分中進行了描述。
您必須設定 s一些非零值才能回傳一些非零值。您不必使用append,但附加到適當的型別是非常標準的,nil因為這樣可以很容易地在回圈中或通過一系列if測驗或其他方式構建串列:
if conditionA {
s = append(s, 42)
}
if conditionB {
s = append(s, 6, 9)
}
但:
if conditionC {
s = []int{3, 1, 4, 1, 5, 9}
}
也會起作用。
無論s最終設定為什么,這就是它在回傳時將保持的。注意:
return someval
表示 (1) 將值分配給 s,然后 (2) 回傳(按此順序)。如果一個延遲函式然后呼叫panic 并且有一個恐慌處理程式可以捕獲恐慌并使用s和/或分配一個新值給s,這很重要;請參閱規范中的 Defer 陳述句示例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/493485.html
上一篇:自動決議body?
