中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go語言中的關鍵字如何使用

發布時間:2023-01-31 14:13:58 來源:億速云 閱讀:178 作者:iii 欄目:編程語言

go語言中關鍵字有25個,分別有:break(退出循環)、default(選擇結構默認項)、func(定義函數)、interface(定義接口)、case(選擇結構標簽)、const(定義常量)、continue、select、chan、continue(跳過本次循環)、defer(延遲執行內容)、go、map、struct、else、goto、package、switch等。

1.概覽

關鍵字(也稱為保留字)是被編程語言保留而不讓編程人員作為標識符使用的字符序列。

關鍵字即是被Go語言賦予了特殊含義的單詞,也可以稱為保留字。

Go語言中的關鍵字一共有 25 個,之所以刻意地將Go語言中的關鍵字保持的這么少,是為了簡化在編譯過程中的代碼解析。和其它語言一樣,關鍵字不能夠作標識符使用。

保留關鍵字說明
break退出循環
default選擇結構默認項(switch、select)
func定義函數
interface定義接口
selectchannel
case選擇結構標簽
chan定義 channel
const常量
continue跳過本次循環
defer延遲執行內容(收尾工作)
go并發執行
mapmap 類型
struct定義結構體
else選擇結構
goto跳轉語句
package
switch選擇結構
fallthrough流程控制
if選擇結構
range從 slice、map 等結構中取元素
type定義類型
for循環
import導入包
return返回
var定義變量

Go的25個關鍵字按照作用可以分為3類,分別為包管理、程序實體聲明與定義與程序流程控制。

類別關鍵字
程序聲明import, package
程序實體聲明和定義chan, const, func, interface, map, struct, type, var
程序控制流程go, select, break, case, continue, default, defer, else, fallthrough, for, goto, if, range, return, switch

說明:

在Go語言中,程序實體的聲明和定義是建立在其數據類型的體系之上的。例如關鍵字chan、func、interface、map和struct,分別于Go語言的復合數據類型Channel(通道)、Function(函數)、Interface(接口)、Map(字典)和Struct(結構體)相對應。

程序控制流程的關鍵字,一共15個。其中go和select,這兩個主要用于Go語言并發編程。

2.包管理

2.1 import

import 用于導入包,這樣就可以使用包中被導出的標識符。導入格式如下:

import _ "package path"
import . "package path"
import alias "package path"

import (
_ "package path"
. "package path"
alias "package path"
)

其中包路徑前面可以有三中修飾符中的某一個。下劃線即空白標識符,表示不使用包中的標識符,只需要包的副作用,即計算包級變量的初始化表達式和執行導入包的init初始化函數。點號代替包的別名, 表示訪問包中的導出標識符無需使用包名。alias則表示包的別名。

導入示例如下:

導入聲明						Sin的本地名
import   "lib/math"         math.Sin
import m "lib/math"         m.Sin
import . "lib/math"         Sin

2.2 package

package用于聲明包的名稱,需放在go文件所有代碼的最前面。一個包由一個或多個go源文件組成,需放在同一個目錄下,且同一個目錄下的這些go文件的package的名字只能有一個。申明格式如下:

package <packagename>

packagename不能為空白標識符_。

3.程序實體聲明與定義

3.1 chan

chan用于聲明channel(信道)。信道提供一種機制使兩個并發執行的函數實現同步,并通過傳遞具體元素類型的值來通信。未初始化的信道值為 nil。聲明格式如下:

chan T      	// 可以被用來發送和接收類型T的值
chan<- T   // 只能被用來發送浮點數
<-chan T       // 只能被用來接收整數

其中<-操作符指定信道的方向,發送或接收。若沒有給定方向,那么該信道就是雙向的。信道可通過類型轉換或賦值被強制為只發送或只接收。

信道的初始化可以通過 make 函數來實現,其結果值充當了對底層數據結構的引用。初始化時可以為信道設置緩沖區大小,默認值是零,表示不帶緩沖的或同步的信道。

ci := make(chan int)            // 整數類型的無緩沖信道
cj := make(chan int, 0)         // 整數類型的無緩沖信道
cp := make(chan *os.File, 100)  // 指向文件指針的帶緩沖信道

3.2 const

const 用于定義常量,一旦創建,不可賦值修改。const可以出現在任何關鍵字 var 可以出現的地方,聲明常量方式與 var 聲明變量方式相同,格式如下:

const name = value
const name T = value
const (
name = value
name T = value
)

注意,Golang 中的 const 不支持像 C/C++ 中修飾函數的參數和返回值,即下面的語句是非法的。

func test(const name *string)
func test(name *string) const *string

3.3 func

func 用于定義函數。Go函數支持變參且返回值支持多個,但不支持默認參數。如果函數存在多個返回值形參則需要使用小括號括起來,定義格式如下:

func funcName(){}							//無參無返回值
func funcName(t T) T {} //有參有返回值
func funcName(t T, list ...T) (T1,T1) {} //有變參有多個返回值

代碼格式上需要注意的是,函數體的第一個大括號必須函數名同行。這個是Go對代碼格式的強制要求,在其它的語句中也是如此,比如if else語句、for語句、switch語句、select語句等。

3.4 interface

interface 用于定義接口。一個接口是一個方法集,如果一個類型實現了一個接口中的所有方法集,那么說明該類型實現此接口。接口類型變量可以存儲任何實現了該接口的類型的值。特別的,interface{}表示空接口類型,默認地,所有類型均實現了空接口,所以interface{}可以接收任意類型值。示例如下:

//空接口
interface{}

//一個簡單的File接口
type File interface {
Read(b Buffer) bool
Write(b Buffer) bool
Close()
}

3.5 map

map 用于聲明映射變量。映射屬容器類類型,是一個同種類型元素的無序組,通過唯一的鍵可以獲取對應的值。可以使用 make 創建 map 變量,未初始化的映射值為 nil。創建map變量主要有如下幾種方式:

//創建0容量的map
var myMap = make(map[T1] T2)

//創建指定容量的map
var myMap = make(map[T]T2, cap)

//創建并初始化map
var myMap = map[string]int {
"dable" : 27,
"cat" : 28,
}

使用示例:

package main

import "fmt"

func main() {
       nameAge := make(map[string]int)
       nameAge["bob"] = 18                     //增
       nameAge["tom"] = 16                     //增
       delete(nameAge, "bob")                  //刪
       nameAge["tom"] = 19                     //改
       v := nameAge["tom"]                     //查
       fmt.Println("v=",v)
       v, ok := nameAge["tom"]                 //查,推薦用法
       if ok {
           fmt.Println("v=",v,"ok=",ok)
       }  
       for k, v :=range nameAge {       //遍歷
               fmt.Println(k, v)
       }  
}

輸出結果:

v= 19
v= 19 ok= true
tom 19

3.6 struct

struct 用于定義結構體。結構體屬容器類類型,是多個相同或不同類型值的集合。

package main

import "fmt"

type Vertex struct {
X, Y int
}

var (
v1 = Vertex{1, 2}  // 類型為 Vertex
v2 = Vertex{X: 1}  // Y:0 被省略
v3 = Vertex{}      // X:0 和 Y:0
p  = &Vertex{1, 2} // 類型為 *Vertex
)

func main() {
fmt.Printf("%#v %#v %#v %#v\n", v1, v2, v3, p)
}

輸出結果:

main.Vertex{X:1, Y:2} main.Vertex{X:1, Y:0} main.Vertex{X:0, Y:0} &main.Vertex{X:1, Y:2}

3.7 type

type 用于定義類型,比如定義struct、interface與等價類型。

//定義struct
type Person struct { name string }

//定義接口
type Person interface {
speak(word string)
}

//定義等價類型,rune等價于int32
type rune int32

3.8 var

var 用于定義變量,語法格式主要有:

var name T			//name默認為類型T的零值
var name = value //根據值value推斷變量name的類型
var name T = value //賦初始值時指明類型
var name1, name2 T //同時定義多個同類型變量

//同時定義多個不同類型的變量
var (
name string ="dable"
age int = 18
)

定義變量可以使用:=來替代var,但是:=運算符只能用于函數體內。

4.程序流程控制

4.1 for range break continue

(1)for 與 range for是Go中唯一用于循環結構的關鍵詞。有三個使用方式,分別是單個循環條件,經典的初始化/條件/后續形式,還有和range關鍵詞結合使用來遍歷容器類對象(數組、切片、映射)。

//單條件
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}

//初始化/條件/后續形式
//注意Go中沒有前置自增與自減運算符,即++i是非法的
for i:=0; i < 3; i++ {
fmt.Println(i)
}

//for range形式遍歷數組
array :=[...]int{0,1,2,3,4,5}
for i, v :=range array{
fmt.Println(i,v)
}

(2)break break用于終止最內層的"for"、“switch"或"select"語句的執行。break可以攜帶標簽,用于跳出多層。如果存在標簽,則標簽必須放在"for”、"switch"或"select"語句開始處。

//終止for
L:
for i < n {
switch i {
case 5:
break L
}
}

(3)continue continue通常用于結束當前循環,提前進入下一輪循環。也可以像break一樣攜帶標簽,此時程序的執行流跳轉到標簽的指定位置,可用于跳出多層"for"、“switch"或"select”,提前進入下一輪的執行。示例如下:

//提前進入下一輪循環
for i:=0; i < 3; i++ {
if i == 1 {
continue
}
fmt.Println(i)
}
//輸出結果
0
2

//提前進入標簽處for的下一輪循環
L:
for i:=0; i < 2; i++ {
for j:=0; j < 3; j++{
if j == 1 {
continue L
}
fmt.Println(i, j)
}
}
//輸出結果
0 0
1 0

4.2 goto

goto用于將程序的執行轉移到與其標簽相應的語句。可以使用goto退出多層"for"、“switch"或"select”,功能類似于break攜帶標簽。

//終止for
L:
for i < n {
switch i {
case 5:
goto L
}
}

注意事項: (1)執行"goto"不能在跳轉過程中跳過變量的定義,不然會報編譯錯誤。例如:

	goto L  //編譯報錯
v := 3
L:
fmt.Println(v)

(2)在塊外的goto語句不能跳轉至該塊中的標簽。例如:

if n%2 == 1 {
goto L1
}
for n > 0 {
f()
n--
L1:
f()
n--
}

是錯誤的,因為標簽 L1 在"for"語句的塊中而 goto 則不在。 (3)程序設計時,應盡量避免使用goto語句,因為程序執行流的隨意跳轉會破壞結構化設計風格,導致代碼可讀性下降。

4.3 switch case default fallthrough

這四個關鍵詞是結合使用的。switch語句提供多路執行,表達式或類型說明符與switch中的case相比較從而決定執行哪一分支。default用于給出默認分支,即所有的case分支都不滿足時執行default分支。Go中的switch語句在執行完某個case子句后,不會再順序地執行后面的case子句,而是結束當前switch語句。使用fallthrough可以繼續執行后面的case與default子句。

下面分別以表達式選擇或類型選擇為例演示switch case default fallthrough的用法。

//表達式選擇

switch tag {
default: s3() //default子句可以出現在switch語句中的任意位置,不一定是最后一個
case 0, 1, 2, 3: s1() //case表達式可以提供多個待匹配的值,使用逗號分隔
case 4, 5, 6, 7: s2()
}

switch x := f(); {
case x < 0: return -x //case表達式無需為常量
default: return x
}

switch { //缺失的switch表達式意為"true"
case x < y: f1()
fallthrough //強制執行下一個case子句
case x < z: f2()
//此處沒有fallthrough,switch執行流在此終止
case x == 4: f3()
}

//類型選擇
switch i := x.(type) {
case int:
printInt(i)                            // i 的類型為 int
case float64:
printFloat64(i)                        // i 的類型為 float64
case func(int) float64:
printFunction(i)                       // i 的類型為 func(int) float64
case bool, string:
printString("type is bool or string")  // i 的類型為 bool or string
default:
printString("don't know the type")     // i 的類型未知
}

4.4 if else

if與else實現條件控制,與C有許多相似之處,但也有其不同之處。變化主要有三點: (1)可省略條件表達式的括號; (2)支持初始化語句,可定義代碼塊局部變量; (3)if與else塊中只有一條語句也需要添加大括號; (4)起始大括號必須與if與else同行。

if err := file.Chmod(0664); err != nil {
log.Print(err)
return err
}

4.5 return defer

(1)return return用于函數執行的終止并可選地提供一個或多個返回值。 任何在函數F中被推遲的函數會在F 返回給其調用者前執行。函數可以通過return返回多個值。如果返回值在函數返回形參中指定了名字,那么return時可不帶返回值列表。

//無返回值
func noResult() {
return
}

//單返回值
func simpleF() int {
return 2
}

//多返回值
func complexF2() (float64, float64) {
re = 7.0
im = 4.0
return re, im
}

//返回值已具名
unc complexF3() (re float64, im float64) {
re = 7.0
im = 4.0
return
}

(2)defer defer語句用于預設一個函數調用,即推遲函數的執行。 該函數會在執行 defer 的函數返回之前立即執行。它顯得非比尋常, 但卻是處理一些事情的有效方式,例如無論以何種路徑返回,都必須釋放資源的函數。 典型的例子就是解鎖互斥和關閉文件。

//將文件的內容作為字符串返回。
func Contents(filename string) (string, error) {
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()  // f.Close 會在函數結束后運行

var result []byte
buf := make([]byte, 100)
for {
n, err := f.Read(buf[0:])
result = append(result, buf[0:n]...)
if err != nil {
if err == io.EOF {
break
}
return "", err  // 我們在這里返回后,f 就會被關閉
}
}
return string(result), nil // 我們在這里返回后,f 就會被關閉
}

推遲諸如 Close 之類的函數調用有兩點好處:第一, 它能確保你不會忘記關閉文件。如果你以后又為該函數添加了新的返回路徑時, 這種情況往往就會發生。第二,它意味著“關閉”離“打開”很近, 這總比將它放在函數結尾處要清晰明了。

使用defer時,需要注意兩點: (a)被推遲函數的實參(如果該函數為方法則還包括接收者)在推遲執行時就會求值,而不是在調用執行時才求值。這樣不僅無需擔心變量值在函數執行時被改變, 同時還意味著可以給被推遲的函數傳遞不同參數。下面是個簡單的例子。

for i := 0; i < 5; i++ {
defer fmt.Printf("%d ", i)
}

(b)被推遲的函數按照后進先出(LIFO)的順序執行,因此以上代碼在函數返回時會打印 4 3 2 1 0。

4.6 go

go用于創建Go程(goroutine),實現并發編程。Go程是與其它Go程并發運行在同一地址空間的函數,相比于線程與進程,它是輕量級的。Go程在多線程操作系統上可實現多路復用,因此若一個線程阻塞,比如說等待I/O,那么其它的線程就會運行。Go程的設計隱藏了線程創建和管理的諸多復雜性。

在函數或方法前添加 go 關鍵字能夠在新的Go程中調用它。當調用完成后,該Go程也會安靜地退出。效果有點像Unix Shell中的 & 符號,它能讓命令在后臺運行。

package main

import (
       "fmt"  
       "time"  
)

func main() {
       go func(){
           fmt.Println("in first goroutine")
       }()    
       go func(){
           fmt.Println("in second goroutine")
       }()    

       fmt.Println("main thread start sleep, and other goroutine start execute")
       time.Sleep(10*time.Second)
}

輸出結果:

main thread start sleep, and other goroutine start execute
in second goroutine
in first goroutine

注意,從輸出結果可以看出,go程的執行順序和創建的順序是沒有關系的,也就是說存在多個go程時,其執行的順序是隨機的。

4.7 select

select語句用來選擇哪個case中的發送或接收操作可以被立即執行。它類似于switch語句,但是它的case涉及channel有關的I/O操作。也就是說select就是用來監聽和channel有關的IO操作,它與select, poll, epoll相似,當IO操作發生時,觸發相應的動作,實現IO多路復用。

package main

import "fmt"

func main(){
   ch2 := make(chan int, 1)
   ch3 := make(chan int, 1)

   ch2 <- 3
   ch3 <- 5

   select {
   case <- ch2:
       fmt.Println("ch2 selected.")
   case <- ch3:
       fmt.Println("ch3 selected.")
default:
//如果ch2與ch3沒有數據到來,則進入default處理流程。如果沒有default子句,則select一直阻塞等待ch2與ch3的數據到來
fmt.Println("default")
}
}

輸出結果:

ch2 selected.

//或者
ch3 selected.

從輸出結果可以看出,當存在多個case滿足條件,即有多個channel存在數據時,會隨機的選擇一個執行。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

吉林市| 昌江| 瓦房店市| 宣恩县| 平泉县| 邛崃市| 孝义市| 昭觉县| 成安县| 涟源市| 新疆| 云南省| 武宣县| 深水埗区| 义马市| 治多县| 内丘县| 富民县| 梅州市| 岳普湖县| 沁阳市| 苍南县| 拜城县| 渝中区| 锦州市| 宁武县| 陈巴尔虎旗| 潞城市| 拉孜县| 新泰市| 凌海市| 邵阳县| 抚顺县| 汝南县| 五家渠市| 怀远县| 贺州市| 东乌珠穆沁旗| 阿图什市| 大渡口区| 庆阳市|