天天看點

Go語言學習筆記

Go 語言資料類型

 Go 語言按類别有以下幾種資料類型:

序号 類型和描述
1

布爾型

布爾型的值隻可以是常量 true 或者 false。一個簡單的例子:var b bool = true。

2

數字類型

整型 int 和浮點型 float,Go 語言支援整型和浮點型數字,并且原生支援複數,其中位的運算采用補碼。

3

字元串類型:

字元串就是一串固定長度的字元連接配接起來的字元序列。Go的字元串是由單個位元組連接配接起來的。Go語言的字元串的位元組使用UTF-8編碼辨別Unicode文本。

4

派生類型:

包括:

  • (a) 指針類型(Pointer)
  • (b) 數組類型
  • (c) 結構化類型(struct)
  • (d) 聯合體類型 (union)
  • (e) 函數類型
  • (f) 切片類型
  • (g) 接口類型(interface)
  • (h) Map 類型
  • (i) Channel 類型

Go 也有基于架構的類型,例如:int、uint 和 uintptr。

uint8

無符号 8 位整型 (0 到 255)

uint16

無符号 16 位整型 (0 到 65535)

uint32

無符号 32 位整型 (0 到 4294967295)

uint64

無符号 64 位整型 (0 到 18446744073709551615)

5

int8

有符号 8 位整型 (-128 到 127)

6

int16

有符号 16 位整型 (-32768 到 32767)

7

int32

有符号 32 位整型 (-2147483648 到 2147483647)

8

int64

有符号 64 位整型 (-9223372036854775808 到 9223372036854775807)

浮點型:

float32

IEEE-754 32位浮點型數

float64

IEEE-754 64位浮點型數

complex64

32 位實數和虛數

complex128

64 位實數和虛數

其他數字類型

以下列出了其他更多的數字類型:

byte

類似 uint8

rune

類似 int32

uint

32 或 64 位

int

與 uint 一樣大小

uintptr

無符号整型,用于存放一個指針

Go 語言變量

變量來源于數學,是計算機語言中能儲存計算結果或能表示值抽象概念。變量可以通過變量名通路。

Go 語言變量名由字母、數字、下劃線組成,其中首個字母不能為數字。

聲明變量的一般形式是使用 var 關鍵字:

var identifier type      

變量聲明

第一種,指定變量類型,聲明後若不指派,使用預設值。

var v_name v_type
v_name = value      

第二種,根據值自行判定變量類型。

var v_name = value      

第三種,省略var, 注意 :=左側的變量不應該是已經聲明過的,否則會導緻編譯錯誤。

v_name := value

// 例如
var a int = 10
var b = 10
c : = 10      

執行個體如下:

package main
var a = "w3cschool菜鳥教程"
var b string = "w3cschool.cc"
var c bool

func main(){
    println(a, b, c)
}      

以上執行個體執行結果為:

w3cschool菜鳥教程 w3cschool.cc false      

多變量聲明

//類型相同多個變量, 非全局變量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3

var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要顯示聲明類型,自動推斷

vname1, vname2, vname3 := v1, v2, v3 //出現在:=左側的變量不應該是已經被聲明過的,否則會導緻編譯錯誤


// 這種因式分解關鍵字的寫法一般用于聲明全局變量
var (
    vname1 v_type1
    vname2 v_type2
)      
package main

var x, y int
var (  // 這種因式分解關鍵字的寫法一般用于聲明全局變量
    a int
    b bool
)

var c, d int = 1, 2
var e, f = 123, "hello"

//這種不帶聲明格式的隻能在函數體中出現
//g, h := 123, "hello"

func main(){
    g, h := 123, "hello"
    println(x, y, a, b, c, d, e, f, g, h)
}      
0 0 0 false 1 2 123 hello 123 hello      

值類型和引用類型

所有像 int、float、bool 和 string 這些基本類型都屬于值類型,使用這些類型的變量直接指向存在記憶體中的值:

Go語言學習筆記

當使用等号 

=

 将一個變量的值指派給另一個變量時,如:

j = i

,實際上是在記憶體中将 i 的值進行了拷貝:

Go語言學習筆記

你可以通過 &i 來擷取變量 i 的記憶體位址,例如:0xf840000040(每次的位址都可能不一樣)。值類型的變量的值存儲在棧中。

記憶體位址會根據機器的不同而有所不同,甚至相同的程式在不同的機器上執行後也會有不同的記憶體位址。因為每台機器可能有不同的存儲器布局,并且位置配置設定也可能不同。

更複雜的資料通常會需要使用多個字,這些資料一般使用引用類型儲存。

一個引用類型的變量 r1 存儲的是 r1 的值所在的記憶體位址(數字),或記憶體位址中第一個字所在的位置。

Go語言學習筆記

這個記憶體位址為稱之為指針,這個指針實際上也被存在另外的某一個字中。

同一個引用類型的指針指向的多個字可以是在連續的記憶體位址中(記憶體布局是連續的),這也是計算效率最高的一種存儲形式;也可以将這些字分散存放在記憶體中,每個字都訓示了下一個字所在的記憶體位址。

當使用指派語句 r2 = r1 時,隻有引用(位址)被複制。

如果 r1 的值被改變了,那麼這個值的所有引用都會指向被修改後的内容,在這個例子中,r2 也會受到影響。

簡短形式,使用 := 指派操作符

我們知道可以在變量的初始化時省略變量的類型而由系統自動推斷,聲明語句寫上 var 關鍵字其實是顯得有些多餘了,是以我們可以将它們簡寫為 a := 50 或 b := false。

a 和 b 的類型(int 和 bool)将由編譯器自動推斷。

這是使用變量的首選形式,但是它隻能被用在函數體内,而不可以用于全局變量的聲明與指派。使用操作符 := 可以高效地建立一個新的變量,稱之為初始化聲明。

注意事項

如果在相同的代碼塊中,我們不可以再次對于相同名稱的變量使用初始化聲明,例如:a := 20 就是不被允許的,編譯器會提示錯誤 no new variables on left side of :=,但是 a = 20 是可以的,因為這是給相同的變量賦予一個新的值。

如果你在定義變量 a 之前使用它,則會得到編譯錯誤 undefined: a。

如果你聲明了一個局部變量卻沒有在相同的代碼塊中使用它,同樣會得到編譯錯誤,例如下面這個例子當中的變量 a:

func main() {
   var a string = "abc"
   fmt.Println("hello, world")
}      

嘗試編譯這段代碼将得到錯誤 a declared and not used。

此外,單純地給 a 指派也是不夠的,這個值必須被使用,是以使用

fmt.Println("hello, world", a)      

會移除錯誤。

但是全局變量是允許聲明但不使用。

>

同一類型的多個變量可以聲明在同一行,如:

var a, b, c int      

多變量可以在同一行進行指派,如:

a, b, c = 5, 7, "abc"      

上面這行假設了變量 a,b 和 c 都已經被聲明,否則的話應該這樣使用:

a, b, c := 5, 7, "abc"      

右邊的這些值以相同的順序指派給左邊的變量,是以 a 的值是 5, b 的值是 7,c 的值是 "abc"。

這被稱為 并行 或 同時 指派。

如果你想要交換兩個變量的值,則可以簡單地使用 a, b = b, a。

空白辨別符 _ 也被用于抛棄值,如值 5 在:_, b = 5, 7 中被抛棄。

_ 實際上是一個隻寫變量,你不能得到它的值。這樣做是因為 Go 語言中你必須使用所有被聲明的變量,但有時你并不需要使用從一個函數得到的所有傳回值。

并行指派也被用于當一個函數傳回多個傳回值時,比如這裡的 val 和錯誤 err 是通過調用 Func1 函數同時得到:val, err = Func1(var1)。

Go 語言常量

常量是一個簡單值的辨別符,在程式運作時,不會被修改的量。

常量中的資料類型隻可以是布爾型、數字型(整數型、浮點型和複數)和字元串型。

常量的定義格式:

const identifier [type] = value      

你可以省略類型說明符 [type],因為編譯器可以根據變量的值來推斷其類型。

  • 顯式類型定義: 

    const b string = "abc"

  • 隐式類型定義: 

    const b = "abc"

多個相同類型的聲明可以簡寫為:

const c_name1, c_name2 = value1, value2      

以下執行個體示範了常量的應用:

package main

import "fmt"

func main() {
   const LENGTH int = 10
   const WIDTH int = 5   
   var area int
   const a, b, c = 1, false, "str" //多重指派

   area = LENGTH * WIDTH
   fmt.Printf("面積為 : %d", area)
   println()
   println(a, b, c)   
}      

以上執行個體運作結果為:

面積為 : 50
1 false str      

常量還可以用作枚舉:

const (
    Unknown = 0
    Female = 1
    Male = 2
)      

數字 0、1 和 2 分别代表未知性别、女性和男性。

常量可以用len(), cap(), unsafe.Sizeof()常量計算表達式的值。常量表達式中,函數必須是内置函數,否則編譯不過:

package main

import "unsafe"
const (
    a = "abc"
    b = len(a)
    c = unsafe.Sizeof(a)
)

func main(){
    println(a, b, c)
}      
abc 3 16      

iota

iota,特殊常量,可以認為是一個可以被編譯器修改的常量。

在每一個const關鍵字出現時,被重置為0,然後再下一個const出現之前,每出現一次iota,其所代表的數字會自動增加1。

iota 可以被用作枚舉值:

const (
    a = iota
    b = iota
    c = iota
)      

第一個 iota 等于 0,每當 iota 在新的一行被使用時,它的值都會自動加 1;是以 a=0, b=1, c=2 可以簡寫為如下形式:

const (
    a = iota
    b
    c
)      

iota 用法

package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //獨立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢複計數
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}      
0 1 2 ha ha 100 100 7 8      

再看個有趣的的 iota 執行個體:

package main

import "fmt"
const (
	i=1<<iota
    j=3<<iota
    k
    l
)

func main() {
	fmt.Println("i=",i)
	fmt.Println("j=",j)
	fmt.Println("k=",k)
	fmt.Println("l=",l)
}      
i= 1
j= 6
k= 12
l= 24      

iota表示從0開始自動加1,是以i=1<<0,j=3<<1(<<表示左移的意思),即:i=1,j=6,這沒問題,關鍵在k和l,從輸出結果看,k=3<<2,l=3<<3。

Go 語言運算符

運算符用于在程式運作時執行數學或邏輯運算。

Go 語言内置的運算符有:

  • 算術運算符
  • 關系運算符
  • 邏輯運算符
  • 位運算符
  • 指派運算符
  • 其他運算符

接下來讓我們來詳細看看各個運算符的介紹。

下表列出了所有Go語言的算術運算符。假定 A 值為 10,B 值為 20。

運算符 描述 執行個體
+ 相加 A + B 輸出結果 30
- 相減 A - B 輸出結果 -10
* 相乘 A * B 輸出結果 200
/ 相除 B / A 輸出結果 2
% 求餘 B % A 輸出結果 0
++ 自增 A++ 輸出結果 11
-- 自減 A-- 輸出結果 9

以下執行個體示範了各個算術運算符的用法:

package main

import "fmt"

func main() {

   var a int = 21
   var b int = 10
   var c int

   c = a + b
   fmt.Printf("第一行 - c 的值為 %d\n", c )
   c = a - b
   fmt.Printf("第二行 - c 的值為 %d\n", c )
   c = a * b
   fmt.Printf("第三行 - c 的值為 %d\n", c )
   c = a / b
   fmt.Printf("第四行 - c 的值為 %d\n", c )
   c = a % b
   fmt.Printf("第五行 - c 的值為 %d\n", c )
   a++
   fmt.Printf("第六行 - c 的值為 %d\n", a )
   a--
   fmt.Printf("第七行 - c 的值為 %d\n", a )
}      

以上執行個體運作結果:

第一行 - c 的值為 31
第二行 - c 的值為 11
第三行 - c 的值為 210
第四行 - c 的值為 2
第五行 - c 的值為 1
第六行 - c 的值為 22
第七行 - c 的值為 21      

下表列出了所有Go語言的關系運算符。假定 A 值為 10,B 值為 20。

== 檢查兩個值是否相等,如果相等傳回 True 否則傳回 False。 (A == B) 為 False
!= 檢查兩個值是否不相等,如果不相等傳回 True 否則傳回 False。 (A != B) 為 True
檢查左邊值是否大于右邊值,如果是傳回 True 否則傳回 False。 (A > B) 為 False
< 檢查左邊值是否小于右邊值,如果是傳回 True 否則傳回 False。 (A < B) 為 True
>= 檢查左邊值是否大于等于右邊值,如果是傳回 True 否則傳回 False。 (A >= B) 為 False
<= 檢查左邊值是否小于等于右邊值,如果是傳回 True 否則傳回 False。 (A <= B) 為 True

以下執行個體示範了關系運算符的用法:

package main

import "fmt"

func main() {
   var a int = 21
   var b int = 10

   if( a == b ) {
      fmt.Printf("第一行 - a 等于 b\n" )
   } else {
      fmt.Printf("第一行 - a 不等于 b\n" )
   }
   if ( a < b ) {
      fmt.Printf("第二行 - a 小于 b\n" )
   } else {
      fmt.Printf("第二行 - a 不小于 b\n" )
   } 
   
   if ( a > b ) {
      fmt.Printf("第三行 - a 大于 b\n" )
   } else {
      fmt.Printf("第三行 - a 不大于 b\n" )
   }
   /* Lets change value of a and b */
   a = 5
   b = 20
   if ( a <= b ) {
      fmt.Printf("第四行 - a 小于等于  b\n" )
   }
   if ( b >= a ) {
      fmt.Printf("第五行 - b 大于等于 b\n" )
   }
}      
第一行 - a 不等于 b
第二行 - a 不小于 b
第三行 - a 大于 b
第四行 - a 小于等于  b
第五行 - b 大于等于 b      

下表列出了所有Go語言的邏輯運算符。假定 A 值為 True,B 值為 False。

&& 邏輯 AND 運算符。 如果兩邊的操作數都是 True,則條件 True,否則為 False。 (A && B) 為 False
|| 邏輯 OR 運算符。 如果兩邊的操作數有一個 True,則條件 True,否則為 False。 (A || B) 為 True
! 邏輯 NOT 運算符。 如果條件為 True,則邏輯 NOT 條件 False,否則為 True。 !(A && B) 為 True

以下執行個體示範了邏輯運算符的用法:

package main

import "fmt"

func main() {
   var a bool = true
   var b bool = false
   if ( a && b ) {
      fmt.Printf("第一行 - 條件為 true\n" )
   }
   if ( a || b ) {
      fmt.Printf("第二行 - 條件為 true\n" )
   }
   /* 修改 a 和 b 的值 */
   a = false
   b = true
   if ( a && b ) {
      fmt.Printf("第三行 - 條件為 true\n" )
   } else {
      fmt.Printf("第三行 - 條件為 false\n" )
   }
   if ( !(a && b) ) {
      fmt.Printf("第四行 - 條件為 true\n" )
   }
}      
第二行 - 條件為 true
第三行 - 條件為 false
第四行 - 條件為 true      

位運算符對整數在記憶體中的二進制位進行操作。

下表列出了位運算符 &, |, 和 ^ 的計算:

p q p & q p | q p ^ q

假定 A = 60; B = 13; 其二進制數轉換為:

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A|B = 0011 1101

A^B = 0011 0001

~A  = 1100 0011      

C 語言支援的位運算符如下表所示。假定 A 為60,B 為13:

& 按位與運算符"&"是雙目運算符。 其功能是參與運算的兩數各對應的二進位相與。 (A & B) 結果為 12, 二進制為 0000 1100
| 按位或運算符"|"是雙目運算符。 其功能是參與運算的兩數各對應的二進位相或 (A | B) 結果為 61, 二進制為 0011 1101
^ 按位異或運算符"^"是雙目運算符。 其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。 (A ^ B) 結果為 49, 二進制為 0011 0001
<< 左移運算符"<<"是雙目運算符。左移n位就是乘以2的n次方。 其功能把"<<"左邊的運算數的各二進位全部左移若幹位,由"<<"右邊的數指定移動的位數,高位丢棄,低位補0。 A << 2 結果為 240 ,二進制為 1111 0000
>> 右移運算符">>"是雙目運算符。右移n位就是除以2的n次方。 其功能是把">>"左邊的運算數的各二進位全部右移若幹位,">>"右邊的數指定移動的位數。 A >> 2 結果為 15 ,二進制為 0000 1111
package main

import "fmt"

func main() {

   var a uint = 60	/* 60 = 0011 1100 */  
   var b uint = 13	/* 13 = 0000 1101 */
   var c uint = 0          

   c = a & b       /* 12 = 0000 1100 */ 
   fmt.Printf("第一行 - c 的值為 %d\n", c )

   c = a | b       /* 61 = 0011 1101 */
   fmt.Printf("第二行 - c 的值為 %d\n", c )

   c = a ^ b       /* 49 = 0011 0001 */
   fmt.Printf("第三行 - c 的值為 %d\n", c )

   c = a << 2     /* 240 = 1111 0000 */
   fmt.Printf("第四行 - c 的值為 %d\n", c )

   c = a >> 2     /* 15 = 0000 1111 */
   fmt.Printf("第五行 - c 的值為 %d\n", c )
}      
第一行 - c 的值為 12
第二行 - c 的值為 61
第三行 - c 的值為 49
第四行 - c 的值為 240
第五行 - c 的值為 15      

下表列出了所有Go語言的指派運算符。

= 簡單的指派運算符,将一個表達式的值賦給一個左值 C = A + B 将 A + B 表達式結果指派給 C
+= 相加後再指派 C += A 等于 C = C + A
-= 相減後再指派 C -= A 等于 C = C - A
*= 相乘後再指派 C *= A 等于 C = C * A
/= 相除後再指派 C /= A 等于 C = C / A
%= 求餘後再指派 C %= A 等于 C = C % A
<<= 左移指派 C <<= 2 等于 C = C << 2
>>= 右移指派 C >>= 2 等于 C = C >> 2
&= 位邏輯與指派 C &= 2 等于 C = C & 2
^= 位邏輯或指派 C ^= 2 等于 C = C ^ 2
|= 位邏輯異或指派 C |= 2 等于 C = C | 2

以下執行個體示範了指派運算符的用法:

package main

import "fmt"

func main() {
   var a int = 21
   var c int

   c =  a
   fmt.Printf("第 1 行 - =  運算符執行個體,c 值為 = %d\n", c )

   c +=  a
   fmt.Printf("第 2 行 - += 運算符執行個體,c 值為 = %d\n", c )

   c -=  a
   fmt.Printf("第 3 行 - -= 運算符執行個體,c 值為 = %d\n", c )

   c *=  a
   fmt.Printf("第 4 行 - *= 運算符執行個體,c 值為 = %d\n", c )

   c /=  a
   fmt.Printf("第 5 行 - /= 運算符執行個體,c 值為 = %d\n", c )

   c  = 200; 

   c <<=  2
   fmt.Printf("第 6行  - <<= 運算符執行個體,c 值為 = %d\n", c )

   c >>=  2
   fmt.Printf("第 7 行 - >>= 運算符執行個體,c 值為 = %d\n", c )

   c &=  2
   fmt.Printf("第 8 行 - &= 運算符執行個體,c 值為 = %d\n", c )

   c ^=  2
   fmt.Printf("第 9 行 - ^= 運算符執行個體,c 值為 = %d\n", c )

   c |=  2
   fmt.Printf("第 10 行 - |= 運算符執行個體,c 值為 = %d\n", c )

}      
第 1 行 - =  運算符執行個體,c 值為 = 21
第 2 行 - += 運算符執行個體,c 值為 = 42
第 3 行 - -= 運算符執行個體,c 值為 = 21
第 4 行 - *= 運算符執行個體,c 值為 = 441
第 5 行 - /= 運算符執行個體,c 值為 = 21
第 6行  - <<= 運算符執行個體,c 值為 = 800
第 7 行 - >>= 運算符執行個體,c 值為 = 200
第 8 行 - &= 運算符執行個體,c 值為 = 0
第 9 行 - ^= 運算符執行個體,c 值為 = 2
第 10 行 - |= 運算符執行個體,c 值為 = 2      

下表列出了Go語言的其他運算符。

傳回變量存儲位址 &a; 将給出變量的實際位址。
指針變量。 *a; 是一個指針變量

以下執行個體示範了其他運算符的用法:

package main

import "fmt"

func main() {
   var a int = 4
   var b int32
   var c float32
   var ptr *int

   /* 運算符執行個體 */
   fmt.Printf("第 1 行 - a 變量類型為 = %T\n", a );
   fmt.Printf("第 2 行 - b 變量類型為 = %T\n", b );
   fmt.Printf("第 3 行 - c 變量類型為 = %T\n", c );

   /*  & 和 * 運算符執行個體 */
   ptr = &a	/* 'ptr' 包含了 'a' 變量的位址 */
   fmt.Printf("a 的值為  %d\n", a);
   fmt.Printf("*ptr 為 %d\n", *ptr);
}      
第 1 行 - a 變量類型為 = int
第 2 行 - b 變量類型為 = int32
第 3 行 - c 變量類型為 = float32
a 的值為  4
*ptr 為 4      

運算符優先級

有些運算符擁有較高的優先級,二進制運算符的運算方向均是從左至右。下表列出了所有運算符以及它們的優先級,由上至下代表優先級由高到低:

優先級
^ !
* / % << >> & &^
+ - | ^
== != < <= >= >
<-

當然,你可以通過使用括号來臨時提升某個表達式的整體運算優先級。

package main

import "fmt"

func main() {
   var a int = 20
   var b int = 10
   var c int = 15
   var d int = 5
   var e int;

   e = (a + b) * c / d;      // ( 30 * 15 ) / 5
   fmt.Printf("(a + b) * c / d 的值為 : %d\n",  e );

   e = ((a + b) * c) / d;    // (30 * 15 ) / 5
   fmt.Printf("((a + b) * c) / d 的值為  : %d\n" ,  e );

   e = (a + b) * (c / d);   // (30) * (15/5)
   fmt.Printf("(a + b) * (c / d) 的值為  : %d\n",  e );

   e = a + (b * c) / d;     //  20 + (150/5)
   fmt.Printf("a + (b * c) / d 的值為  : %d\n" ,  e );      
}      
(a + b) * c / d 的值為 : 90
((a + b) * c) / d 的值為  : 90
(a + b) * (c / d) 的值為  : 90
a + (b * c) / d 的值為  : 50

      

Go 語言條件語句

條件語句需要開發者通過指定一個或多個條件,并通過測試條件是否為 true 來決定是否執行指定語句,并在條件為 false 的情況在執行另外的語句。

下圖展示了程式語言中條件語句的結構:

Go語言學習筆記

Go 語言 if 語句

Go 語言提供了以下幾種條件判斷語句:

if 語句由布爾表達式後緊跟一個或多個語句組成。

文法

Go 程式設計語言中 if 語句的文法如下:

if 布爾表達式 {
   /* 在布爾表達式為 true 時執行 */
}      

If 在布爾表達式為 true 時,其後緊跟的語句塊執行,如果為 false 則不執行。

流程圖如下:

Go語言學習筆記

package main

import "fmt"

func main() {
   /* 定義局部變量 */
   var a int = 10
 
   /* 使用 if 語句判斷布爾表達式 */
   if a < 20 {
       /* 如果條件為 true 則執行以下語句 */
       fmt.Printf("a 小于 20\n" )
   }
   fmt.Printf("a 的值為 : %d\n", a)
}      

以上代碼執行結果為:

a 小于 20
a 的值為 : 10


      

Go 語言 if...else 語句

if 語句 後可以使用可選的 else 語句, else 語句中的表達式在布爾表達式為 false 時執行。

Go 程式設計語言中 if...else 語句的文法如下:

if 布爾表達式 {
   /* 在布爾表達式為 true 時執行 */
} else {
  /* 在布爾表達式為 false 時執行 */
}
      

If 在布爾表達式為 true 時,其後緊跟的語句塊執行,如果為 false 則執行 else 語句塊。

Go語言學習筆記

package main

import "fmt"

func main() {
   /* 局部變量定義 */
   var a int = 100;
 
   /* 判斷布爾表達式 */
   if a < 20 {
       /* 如果條件為 true 則執行以下語句 */
       fmt.Printf("a 小于 20\n" );
   } else {
       /* 如果條件為 false 則執行以下語句 */
       fmt.Printf("a 不小于 20\n" );
   }
   fmt.Printf("a 的值為 : %d\n", a);

}
      
a 不小于 20
a 的值為 : 100      

Go 語言 if 語句嵌套

你可以在 if 或 else if 語句中嵌入一個或多個 if 或 else if 語句。

if 布爾表達式 1 {
   /* 在布爾表達式 1 為 true 時執行 */
   if 布爾表達式 2 {
      /* 在布爾表達式 2 為 true 時執行 */
   }
}
      

你可以以同樣的方式在 if 語句中嵌套 else if...else 語句

package main

import "fmt"

func main() {
   /* 定義局部變量 */
   var a int = 100
   var b int = 200
 
   /* 判斷條件 */
   if a == 100 {
       /* if 條件語句為 true 執行 */
       if b == 200 {
          /* if 條件語句為 true 執行 */
          fmt.Printf("a 的值為 100 , b 的值為 200\n" );
       }
   }
   fmt.Printf("a 值為 : %d\n", a );
   fmt.Printf("b 值為 : %d\n", b );
}
      
a 的值為 100 , b 的值為 200
a 值為 : 100
b 值為 : 200      

Go 語言 switch 語句

switch 語句用于基于不同條件執行不同動作,每一個 case 分支都是唯一的,從上直下逐一測試,直到比對為止。。

switch 語句執行的過程從上至下,直到找到比對項,比對項後面也不需要再加break

Go 程式設計語言中 switch 語句的文法如下:

switch var1 {
    case val1:
        ...
    case val2:
        ...
    default:
        ...
}      

變量 var1 可以是任何類型,而 val1 和 val2 則可以是同類型的任意值。類型不被局限于常量或整數,但必須是相同的類型;或者最終結果為相同類型的表達式。

您可以同時測試多個可能符合條件的值,使用逗号分割它們,例如:case val1, val2, val3。

流程圖:

Go語言學習筆記

package main

import "fmt"

func main() {
   /* 定義局部變量 */
   var grade string = "B"
   var marks int = 90

   switch marks {
      case 90: grade = "A"
      case 80: grade = "B"
      case 50,60,70 : grade = "C"
      default: grade = "D"  
   }

   switch {
      case grade == "A" :
         fmt.Printf("優秀!\n" )     
      case grade == "B", grade == "C" :
         fmt.Printf("良好\n" )      
      case grade == "D" :
         fmt.Printf("及格\n" )      
      case grade == "F":
         fmt.Printf("不及格\n" )
      default:
         fmt.Printf("差\n" );
   }
   fmt.Printf("你的等級是 %s\n", grade );      
}      
優秀!
你的等級是 A      

Type Switch

switch 語句還可以被用于 type-switch 來判斷某個 interface 變量中實際存儲的變量類型。

Type Switch 文法格式如下:

switch x.(type){
    case type:
       statement(s);      
    case type:
       statement(s); 
    /* 你可以定義任意個數的case */
    default: /* 可選 */
       statement(s);
}      

package main

import "fmt"

func main() {
   var x interface{}
     
   switch i := x.(type) {
      case nil:	  
         fmt.Printf(" x 的類型 :%T",i)                
      case int:	  
         fmt.Printf("x 是 int 型")                       
      case float64:
         fmt.Printf("x 是 float64 型")           
      case func(int) float64:
         fmt.Printf("x 是 func(int) 型")                      
      case bool, string:
         fmt.Printf("x 是 bool 或 string 型" )       
      default:
         fmt.Printf("未知型")     
   }   
}      
x 的類型 :<nil>      

Go 語言 select 語句

select是Go中的一個控制結構,類似于用于通信的switch語句。每個case必須是一個通信操作,要麼是發送要麼是接收。

select随機執行一個可運作的case。如果沒有case可運作,它将阻塞,直到有case可運作。一個預設的子句應該總是可運作的。

Go 程式設計語言中 select 語句的文法如下:

select {
    case communication clause  :
       statement(s);      
    case communication clause  :
       statement(s); 
    /* 你可以定義任意數量的 case */
    default : /* 可選 */
       statement(s);
}      

以下描述了 select 語句的文法:

  • 每個case都必須是一個通信
  • 所有channel表達式都會被求值
  • 所有被發送的表達式都會被求值
  • 如果任意某個通信可以進行,它就執行;其他被忽略。
  • 如果有多個case都可以運作,Select會随機公平地選出一個執行。其他不會執行。 

    否則:

    1. 如果有default子句,則執行該語句。
    2. 如果沒有default字句,select将阻塞,直到某個通信可以運作;Go不會重新對channel或值進行求值。

package main

import "fmt"

func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      default:
         fmt.Printf("no communication\n")
   }    
}      
no communication      

熬夜不易,點選請老王喝杯烈酒!!!!!!!