Go習慣用法(多值賦值短變量聲明賦值簡寫模式)基礎(chǔ)實例
1. 多值賦值
可以一次性聲明多個變量,并可以在聲明時賦值,而且可以省略類型,但必須遵守一定的規(guī)則要求。
package main
import "fmt"
func main() {
var x, y int // 相同類型變量可以在末尾帶上類型
var a, b int = 1, 2
var c, d = 3, 4 // 不帶類型時,編譯器自動推斷
var ( // 不同類型變量聲明和隱式初始化
e int
f 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 語言的語法允許多值短變量聲明和賦值的多個變量中,只要有一個是新變量就可以使用 := 進行賦值。
也就是說,在多值短變量的聲明和賦值時, 至少有一個變量是新創(chuàng)建的局部變量,其他的變量可以復用以前的變量,不是新創(chuàng)建的變量執(zhí)行的僅僅是賦值。
package main
import "fmt"
func main() {
var a int = 0
var b int = 0
a, b := 1, 2
fmt.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 中已經(jīng)存在一個局部變量 a ,則賦值語句不會創(chuàng)建新的變量 a , 而是使用 1 賦值給已經(jīng)聲明的局部變量。但是會創(chuàng)建新的變量 b 并給其賦值。
賦值操作符 = 和 := 的區(qū)別:
=不會聲明并創(chuàng)建新變量,而是在當前賦值語句所在的作用域由內(nèi)向外逐層去搜尋變量,如果沒有搜索到相同的變量名,則報編譯錯誤。:=必須出現(xiàn)在函數(shù)或者類型方法內(nèi)部。:=至少要創(chuàng)建一個局部變量并初始化。
多值短變量聲明賦值 := 的最佳使用場景是在錯誤處理上。例如:
a, err := f()
if err ! = nil {
// do something
}
// 此時 err 可以是已存在的 err 變量,只是重新賦值了
b, err := g()3. 簡寫模式
Go 語言很多重復的引用或聲明可以用 () 進行簡寫。
import 多個包;
// 推薦寫法
import (
"os"
"fmt"
)
// 不推薦寫法
import "os"
import "fmt"多個變量聲明;
包中多個相關(guān)全局變量聲明時,建議使用 () 進行合并聲明
// 推薦寫法
var (
uploadStatus bool
downStatus bool
)
// 不推薦寫法
var uploadStatus bool
var uploadStatus bool4. 多值返回函數(shù)
多值返回函數(shù)里如果有 error 或 bool 類型的返回值,則應(yīng)該將 error 和 bool 作為最后一個返回值。這是一種編程風格,沒有對錯。
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 表達式用法有以下幾種情況:
獲取 map 值
獲取 map 中不存在鍵的值不會發(fā)生異常,而是會返回值類型的零值,如果想確定 map 中是否存在某個 key,則可以使用獲取 map 值的 comma, ok 語法。示例如下:
m := make(map[string] string)
v, ok := m["camera"]
if ok {
Println("camera exist")
} else {
Println("camera not exist")
}
讀取 chan 值
讀取已經(jīng)關(guān)閉的通道不會阻塞,也不會引起 panic, 而是一直返回該通道的零值,判斷通道關(guān)閉有兩種方法,一種是 comma, ok 表達式;另一種是通過 range 循環(huán)迭代。
c := make(chan int)
go func() {
c <- 1
c <- 2
close(c)
}()
for {
v, ok := <- c
if ok {
Println("v exist")
} else {
Println("v not exist")
}
}
for v := range c {
Println(v)
}類型斷言
如果 map 查找、類型斷言或通道接收出現(xiàn)在賦值語句的右邊,它們都可能會產(chǎn)生兩個結(jié)果,有一個額外的布爾結(jié)果表示操作是否成功:
v, ok = m[key] // map lookup v, ok = x.(T) // type assertion v, ok = <-ch // channel receive
注意:map 查找、類型斷言或通道接收出現(xiàn)在賦值語句的右邊時,并不一定是產(chǎn)生兩個結(jié)果,也可能只產(chǎn)生一個結(jié)果。對于只產(chǎn)生一個結(jié)果的情形, map 查找失敗時會返回零值,類型斷言失敗時會發(fā)生運行時 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) // 丟棄字節(jié)數(shù) _, ok = x.(T) // 只檢測類型,忽略具體值
6. 傳值規(guī)則
Go 只有一種參數(shù)傳遞規(guī)則,那就是值拷貝,這種規(guī)則包括兩種含義:
函數(shù)參數(shù)傳遞時使用的是值拷貝。
實例賦值給接口變量,接口對實例的引用是值拷貝。
有時在明明是值拷貝的地方,結(jié)果卻修改了變量的內(nèi)容,有以下兩種情況:
直接傳遞的是指針。指針傳遞同樣是值拷貝,但指針和指針副本的值指向的地址是同一個地方,所以能修改實參值。
參數(shù)是復合數(shù)據(jù)類型,這些復合數(shù)據(jù)類型內(nèi)部有指針類型的元素,此時參數(shù)的值拷貝并不影響指針的指向。
Go 復合類型中 chan 、 map 、 slice 、 interface 內(nèi)部都是通過指針指向具體的數(shù)據(jù),這些類型的變量在作為函數(shù)參數(shù)傳遞時,實際上相當于指針的副本。
package main
import "fmt"
func main() {
var x, y int = 3, 5
fmt.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 int
tmp = x
x = y
y = tmp
return x, y
}
func swap_reference(x *int, y *int) (int, int) {
var tmp int
tmp = *x
*x = *y
*y = tmp
return *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習慣用法(多值賦值短變量聲明賦值簡寫模式)基礎(chǔ)實例的詳細內(nèi)容,更多關(guān)于Go多值賦值短變量聲明的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mac下golang安裝了windows編譯環(huán)境后編譯變慢
這篇文章主要介紹了mac下golang安裝了windows編譯環(huán)境后編譯變慢的處理方法,非常的簡單,有相同問題的小伙伴可以參考下。2015-04-04
go?doudou開發(fā)gRPC服務(wù)快速上手實現(xiàn)詳解
這篇文章主要為大家介紹了go?doudou開發(fā)gRPC服務(wù)快速上手實現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
pytorch中的transforms.ToTensor和transforms.Normalize的實現(xiàn)
本文主要介紹了pytorch中的transforms.ToTensor和transforms.Normalize的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04

