日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go 学习笔记(26)— Go 习惯用法(多值赋值,短变量声明和赋值,简写模式、多值返回函数、comma,ok 表达式、传值规则)

發布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go 学习笔记(26)— Go 习惯用法(多值赋值,短变量声明和赋值,简写模式、多值返回函数、comma,ok 表达式、传值规则) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 多值賦值

可以一次性聲明多個變量,并可以在聲明時賦值,而且可以省略類型,但必須遵守一定的規則要求。

package main import "fmt"func main() {var x, y int  // 相同類型變量可以在末尾帶上類型var a, b int = 1, 2var c, d = 3, 4 // 不帶類型時,編譯器自動推斷var (  // 不同類型變量聲明和隱式初始化e intf string)var g int, e int = 6, 7  // 多賦值語句中每個變量后面不能都帶上類型fmt.Println("x ", x)fmt.Println("y ", y)fmt.Println("a ", a)fmt.Println("b ", b)fmt.Println("c ", c)fmt.Println("d ", d)fmt.Println("e ", e)fmt.Println("f ", f)
}

有如下錯誤:

.\main.go:14:14: syntax error: unexpected comma at end of statement

2. 短變量的聲明和賦值

Go 語言的語法允許多值短變量聲明和賦值的多個變量中,只要有一個是新變量就可以使用“:=”進行賦值。

也就是說,在多值短變量的聲明和賦值時, 至少有一個變量是新創建的局部變量,其他的變量可以復用以前的變量,不是新創建的變量執行的僅僅是賦值。

package main import "fmt"func main() {var a int = 0var b int = 0a, b := 1, 2fmt.Println("a ", a)fmt.Println("b ", b)
}

會有以下錯誤:

 .\main.go:8:10: no new variables on left side of :=

要想通過編譯, a, b := 1, 2 至少一個變量是新定義的局部變量,如果在賦值語句 a, b := 1, 2 中已經存在一個局部變量 a ,則賦值語句不會創建新的變量 a , 而是使用 1 賦值給已經聲明的局部變量。但是會創建新的變量 b 并給其賦值。

賦值操作符 := 的區別:

  1. 不會聲明并創建新變量,而是在當前賦值語句所在的作用域由內向外逐層去搜尋變量,如果沒有搜索到相同的變量名,則報編譯錯誤。

  2. := 必須出現在函數或者類型方法內部。

  3. := 至少要創建一個局部變量并初始化。

多值短變量聲明賦值 := 的最佳使用場景是在錯誤處理上。例如:

a, err := f()
if err ! = nil {// do something
}// 此時 err 可以是已存在的 err 變量,只是重新賦值了b, err := g()

3. 簡寫模式

Go 語言很多重復的引用或聲明可以用 () 進行簡寫。

  1. import 多個包;
// 推薦寫法
import ("os""fmt"
)// 不推薦寫法
import "os"
import "fmt"
  1. 多個變量聲明;

包中多個相關全局變量聲明時,建議使用 () 進行合并聲明

// 推薦寫法
var (uploadStatus booldownStatus bool
)// 不推薦寫法
var uploadStatus bool
var uploadStatus bool

4. 多值返回函數

多值返回函數里如果有 errorbool 類型的返回值,則應該將 errorbool 作為最后一個返回值。這是一種編程風格,沒有對錯。

buffer.go:107: func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
buffer.go:335: func (b *Buffer) ReadByte() (byte , error) {

5. comma,ok 表達式

常見的幾個 comma, ok 表達式用法有以下幾種情況:

  1. 獲取 map

獲取 map 中不存在鍵的值不會發生異常,而是會返回值類型的零值,如果想確定 map 中是否存在某個 key,則可以使用獲取 map 值的 comma, ok語法。 示例如下:

m := make(map[string] string)
v, ok := m["camera"]
if ok {Println("camera exist")
} else {Println("camera not exist")
}
  1. 讀取 chan

讀取已經關閉的通道不會阻塞,也不會引起 panic, 而是一直返回該通道的零值,判斷通道關閉有兩種方法,一種是 comma, ok 表達式;另一種是通過 range 循環迭代。

c := make(chan int)
go func() {c <- 1c <- 2close(c)
}()for {v, ok := <- cif ok {Println("v exist")} else {Println("v not exist")}}for v := range c {Println(v)
}
  1. 類型斷言
v, ok = x.(T)              // type assertion

如果 map 查找、類型斷言或通道接收出現在賦值語句的右邊,它們都可能會產生兩個結果,有一個額外的布爾結果表示操作是否成功:

v, ok = m[key]             // map lookup
v, ok = x.(T)              // type assertion
v, ok = <-ch               // channel receive

注意: map 查找、類型斷言或通道接收出現在賦值語句的右邊時,并不一定是產生兩個結果,也可能只產生一個結果。對于只產生一個結果的情形, map 查找失敗時會返回零值,類型斷言失敗時會發生運行時 panic 異常,通道接收失敗時會返回零值(阻塞不算是失敗)。例如下面的例子:

v = m[key]                // map查找,失敗時返回零值
v = x.(T)                 // type斷言,失敗時panic異常
v = <-ch                  // 管道接收,失敗時返回零值(阻塞不算是失敗)
_, ok = m[key]            // map返回2個值
_, ok = mm[""], false     // map返回1個值
_ = mm[""]                // map返回1個值

和變量聲明一樣,我們可以用下劃線空白標識符 _ 來丟棄不需要的值。

_, err = io.Copy(dst, src) // 丟棄字節數
_, ok = x.(T)              // 只檢測類型,忽略具體值

6. 傳值規則

Go 只有一種參數傳遞規則,那就是值拷貝,這種規則包括兩種含義:

  1. 函數參數傳遞時使用的是值拷貝。

  2. 實例賦值給接口變量,接口對實例的引用是值拷貝。

有時在明明是值拷貝的地方,結果卻修改了變量的內容,有以下兩種情況:

  1. 直接傳遞的是指針。指針傳遞同樣是值拷貝,但指針和指針副本的值指向的地址是同一個地方,所以能修改實參值。

  2. 參數是復合數據類型,這些復合數據類型內部有指針類型的元素,此時參數的值拷貝并不影響指針的指向。

Go 復合類型中 chanmapsliceinterface 內部都是通過指針指向具體的數據,這些類型的變量在作為函數參數傳遞時,實際上相當于指針的副本。

package mainimport "fmt"func main() {var x, y int = 3, 5fmt.Printf("befor swap x is %d\n", x)fmt.Printf("befor swapy is %d\n", y)x, y = swap_value(x, y)fmt.Printf("after swap x is %d\n", x)fmt.Printf("after swap y is %d\n", y)x, y = swap_reference(&x, &y)fmt.Printf("after swap_reference x is %d\n", x)fmt.Printf("after swap_reference y is %d\n", y)
}func swap_value(x int, y int) (int, int) {var tmp inttmp = xx = yy = tmpreturn x, y}func swap_reference(x *int, y *int) (int, int) {var tmp inttmp = *x*x = *y*y = tmpreturn *x, *y}

輸出:

befor swap x is 3
befor swapy is 5
after swap x is 5
after swap y is 3
after swap_reference x is 3
after swap_reference y is 5

總結

以上是生活随笔為你收集整理的Go 学习笔记(26)— Go 习惯用法(多值赋值,短变量声明和赋值,简写模式、多值返回函数、comma,ok 表达式、传值规则)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。