1. 程式人生 > 實用技巧 >Go語言的學習之旅【三】

Go語言的學習之旅【三】

一、常量

	const a int = 123 //常量定義const,顯式
	//a = 456 //修改常量值,會報錯 Cannot assign to a,無法賦值
	const b = 23 //隱式
	const c,d = 1,"s" //多重賦值
	const e,f int = 6,7 //多重賦值,同類型
	const (//常量列舉
		g = 1
		h = "asb"
		i = len(h)
	)
	fmt.Println(a,b,c,d,e,f,g,h,i)
	//iota 特殊常量,在定義是為0,後面每行都會計數+1
	const (
		j = iota
		k = iota //同一個const中,iota會計數
		l	//即使不繼續賦值也會計數
		m = "abc" //即使定義其他數,iota還是會計數
		n 			//這時候n都值為上一個m都值,不過iota還是計數
		o = iota	//此時不受m影響,iota繼續計數
	)
	const p = iota //這時候iota會重新整理計數
	fmt.Println(j,k,l,m,n,o,p)
	const (
		q = 1<<iota //1左移0
		r = 3<<iota //3左移1
		s	//這個時候s都值為,3 << 2
		t   //t為 3 << 3
	)//可以認為s不僅僅只是取上一個r的結果,而是r的內容,t同理
	fmt.Println(q,r,s,t)

  

二、運算子

	//算術運算子
	var a = 1+1
	b := 2-1
	c := 10*9
	d := 10/3 //預設int整型型別,答案是3
	e := 8%2 //取模(求餘)
	a++	//自增
	b-- //自減
	//++a,--a這樣的寫法不允許
	//f := a++ 這樣的組合也不被允許
	fmt.Println(a,b,c,d,e)
	//關係運算符
	var g int = 1
	var h int = 2
	if g == h{ //if(g==h)帶括號也是可以的
		fmt.Println("相等")
	}else {
		fmt.Println("不相等")
	}
	if(g < h){
		fmt.Println("g小於h")
	}else{
		fmt.Println("g大於h")
	}
	if(g <= h){
		fmt.Println("g小於等於h")
	}else{
		fmt.Println("g不小於等於h(g大於h)")
	}
	//邏輯運算子
	var i bool = true
	var j bool = false
	if(i && j){//i且j都為真
		fmt.Println("i,j都為true")
	}else{
		fmt.Println("i,j存在一個為false,或者都為false")
	}
	if(i || j){//i或j為真
		fmt.Println("i為true,或者j為true")
	}else{
		fmt.Println("i跟j都為false")
	}
	if(!(i && j)){
		fmt.Println("(i && j)為false,在取反為true")
	}else{
		fmt.Println("(i && j)為true,在取反為false")
	}
	//位運算子
	/*
		k=60, 二進位制 0011 1100
		l=13 	    0000 1101
	 */
	var k,l = 60, 13
	m := k & l //且 1=1&1,m二進位制 0000 1100
	n := k | l //或 1=1|0, n二進位制 0011 1101
	o := k ^ l //異或 1 = 1^0, o二進位制 0011 0001
	p := k << 1 //左移  0011 1100 向左移動1位,p二進位制0111 1000
	q := k >> 1 //右移  0011 1100 向左移動1位,p二進位制0001 1110
	fmt.Println(m,n,o,p,q)
	//賦值運算子
	var r int

	r = k //簡單都賦值
	fmt.Println(r,k,r)

	r += k //等於r = r + k
	fmt.Println(r,k,r)

	r -= k //同上
	fmt.Println(r,k,r)

	r *= k //同上
	fmt.Println(r,k,r)

	r /= k //同上
	fmt.Println(r,k,r)

	r %= k //同上
	fmt.Println(r,k,r)

	r <<=k  //同上
	fmt.Println(r,k,r)

	r >>=k  //同上
	fmt.Println(r,k,r)

	r &= k  //同上
	fmt.Println(r,k,r)

	r |= k  //同上
	fmt.Println(r,k,r)

	r ^=k  //同上
	fmt.Println(r,k,r)

	//其他運算子
	var s *int
	fmt.Println(&r) //表示取到r的記憶體地址
	r = 10
	s = &r
	fmt.Println(*s) //這個是一個指標
	fmt.Println(s)//指標地址

	//運算子優先順序
	/*由上至下 (優先順序遞減),同級由左到右(優先順序遞減),
	符號 * / % << >> & &^
	符號 + - | ^
	符號 == != < <= > >=
	符號 &&
	符號 ||
	*/

三、條件與迴圈

  

func main() {
	//if...else...語句
	var a int = 1
	if a == 1 {
		fmt.Println("a等於1")
		if a > 0 { //巢狀if語句
			fmt.Println("a大於0")
		}
	} else {
		fmt.Println("a不等於1")
	}
	//switch語句
	switch a {
	case 1:
		fmt.Println("a等於1")
	case 2:
		fmt.Println("a等於2")
	default:
		fmt.Println("上面條件都不符合")
	}
	//select語句
	//select 是 Go 中的一個控制結構,類似於用於通訊的 switch 語句。每個 case 必須是一個通訊操作,要麼是傳送要麼是接收。
	//select 隨機執行一個可執行的 case。如果沒有 case 可執行,它將阻塞,直到有 case 可執行。一個預設的子句應該總是可執行的。
	var i, j, k, ch, stopCh chan int //定義通訊int型別
	var o, p int
	select {
	case o = <-i:
		fmt.Println("received", o, "from i")
	case j <- p://阻塞
		fmt.Println("sent ", p, " to j")
	case q, ok := (<-k)://這裡是q := <-k, ok是接收狀態(非阻塞)會造成cpu使用高
		if ok {
			fmt.Println("received", q, " from k")
		} else {
			fmt.Println("k is closed")
		}
	default:
		fmt.Println(" no communication")
	}
	//構建通道
	ch = make(chan int)
	stopCh = make(chan int)
	//併發匿名函式
	go func() {
		// 從3迴圈到0
		for v := 3; v >= 0; v-- {
			// 傳送3到0之間的數值
			ch <- v
			// 每次傳送完時等待
			time.Sleep(time.Second)
		}
		stopCh <- 1
	}()
	fmt.Println("-------------")
	// 遍歷接收通道資料
	for {
		select {
		case x := <- ch:
			fmt.Println("received x ", x)
		case y := <- ch:
			fmt.Println("received y ", y)
		case _ = <- stopCh:
			goto end //跳轉操作
		}
	}
end:
}

 

//迴圈體
for i := 0; i < 100; i++{
   if(i == 0){
      continue //跳過此次迴圈
   }
   if(i == 66){
      break //跳出迴圈
   }
   fmt.Println("i:",i)
}
for i := 0; i < 100; i++{
   if(i == 55){
      goto end   //跳到end處
   }
   fmt.Println("ii:",i)
}
end:
   fmt.Println("結尾end")
var j int = 100
for {//死迴圈,也可以 for true{}
   j--
   if(j == 0){
      break
   }
   fmt.Println("j:",j)
}
fmt.Println("退出")

  

 

四、函式

package main

import "fmt"

//全域性變數
var g int = 10
//宣告一個函式型別
type cb func(int) int

func main() {
	fmt.Println("Hello, World!")
	var x,y int = 1,2
	g = x + y
	fmt.Println("g:",g)
     //重新定義g
     var g int = 20
     //這裡會優先使用區域性引數g
     fmt.Println("區域性g:",g);
a, b := swap(1, 2) fmt.Println(a, b) var c, d = 4, 5 swap2(&c, &d) fmt.Println(c, d) r := test(10, func(i int) int { //直接傳入匿名函式 return i }) fmt.Println(r) t := test(100, callback) fmt.Println(t) } //函式作為引數傳遞 func test(x int, f cb) int { return f(x) } func callback(x int) int { fmt.Println("自定義回撥函式",g) return x } //交換值,引用傳遞 func swap2(x *int, y *int) { var temp int temp = *x *x = *y *y = temp } //交換值 func swap(x int, y int) (int, int) { var temp int temp = x x = y y = temp return x, y }

  

五、總結

  go語言中常量設定是不可修改,運算子型別跟其他語言相差無幾,主要自增、自減沒有++i,--i,a=i++這樣的操作。條件跟迴圈大部分語言一致,條件語句還新增select語句(咋一看還以為是sql語法),其實是專門給訊號判斷的一個語句。還保留了goto end跳轉語法。函式方法很喜歡,雖然跟c挺像的。整體還是很好接受,有一點其他語言基礎的(特別是c語言),還是很快上手!