1. 程式人生 > >這個時代,作為程式設計師可能要學習小程式

這個時代,作為程式設計師可能要學習小程式

最近想搞搞後臺開發,話說注意力就轉移到了公司用的golang。用Go做微服務比較方便,或許是因為golang強悍的語法吧,看到go的語法,自己已被深深的吸引。關於學習後臺如何選擇可以參考《做後臺是選擇Java 、Go ,還是 PHP?》

來我們一起感受下Go的風騷式的程式碼風格。

1、魔鬼式變數宣告

2、陣列的宣告

array就是陣列,它的定義方式如下:

var arr [n]type

在[n]type中,n表示陣列的長度,type表示儲存元素的型別。對陣列的操作和其它語言類似,都是通過[]來進行 讀取或賦值:

var arr [10]int  // 聲明瞭一個int型別的陣列 
arr[0] = 42      // 陣列下標是從0開始的 
arr[1] = 13      // 賦值操作 
fmt.Printf("The first element is %d\n", arr[0])  // 獲取資料,返回42 
fmt.Printf("The last element is %d\n", arr[9]) //返回未賦值的最後一個元素,預設返回0 

由於長度也是陣列型別的一部分,因此[3]int與[4]int是不同的型別,陣列也就不能改變長度。陣列之間的賦值是 值的賦值,即當把一個數組作為引數傳入函式的時候,傳入的其實是該陣列的副本,而不是它的指標。如果要使用指 針,那麼就需要用到後面介紹的slice型別了。

陣列可以使用另一種:=來宣告

a := [3]int{1, 2, 3} // 聲明瞭一個長度為3的int陣列 
b := [10]int{1, 2, 3} // 聲明瞭一個長度為10的int陣列,其中前三個元素初始化為1、2、3,其它預設為0 
c := [...]int{4, 5, 6} // 可以省略長度而採用`...`的方式,Go會自動根據元素個數來計算長度

3、 go語言強大的slice操作

golang 中的 slice 非常強大,讓陣列操作非常方便高效。在開發中不定長度表示的陣列全部都是 slice 。但是很多同學對 slice 的模糊認識,造成認為golang中的陣列是引用型別,結果就是在實際開發中碰到很多坑,以至於出現一些莫名奇妙的問題,陣列中的資料丟失了 slice 的資料結構,它很簡單,一個指向真實 array 地址的指標 ptrslice 的長度 len 和容量 cap

其中 len 和 cap 就是我們在呼叫 len(slice) 和 cap(slice) 返回的值。

我們來按照 slice 的資料結構定義來解析出 ptr, len, cap

// 按照上圖定義的資料結構

type Slice struct {
    ptr   unsafe.Pointer        // Array pointer
    len   int               // slice length
    cap     int               // slice capacity

示例程式碼

4、map的宣告

注意由於go語言是一個強型別的語言,因此hashmap也是有型別的,具體體現在key和value都必須指定型別,比如宣告一個key為string,value也是string的map, 需要這樣做

go語言中的列舉

5、for迴圈的遍歷

func formapTest() {
	var arrayi= [...] int{1, 2, 3, 4, 5, 6, 7, 78, 9, 10}
	for index, c := range arrayi {
		fmt.Printf("array[%d] = %d", index, c)
	}

	str := "go語言的學習和啪啪"
	for i, ch := range str {
		fmt.Println(i, ch) //ch的型別為rune unicode編碼
	}
	//輸出為:28907  (Unicode編碼時,兩個位元組代表一個字元)

	n := len(str)
	for i := 0; i < n; i++ {
		ch := str[i] // 依據下標取字串中的字元,型別為byte
		fmt.Println(i, ch)
		//輸出為utf-8編碼,一個漢字字元佔三個位元組
	}

	array := []rune(str)
	n = len(array)
	for i := 0; i < n; i++ {
		ch := array[i]     // 依據下標取字串中的字元,型別為byte
		 fmt.Println(i, ch) //unicode 編碼轉十進位制輸出
		//golang中字元型別的實際資料型別為uint32,以for迴圈遍歷的方式輸出結果都是Unicode編碼的
	}
	//var str string= "yyh,hello,卡卡論壇,好厲害哦"
	//fmt.Print(str)
	fmt.Print("\n================================\n")
	for i , ch :=  range str{
		//fmt.Printf("(%d, %c)",i,ch)
		fmt.Printf("(%d, %x)",i,ch)
	}

	fmt.Print(utf8.RuneCountInString(str))
	fmt.Print("================================\n")
	bytes := [] byte(str)

	//for len(bytes) > 0 {
		r, size := utf8.DecodeRune(bytes)
		fmt.Printf("%c  %d",r,size)
	//}
	fmt.Println()
	fmt.Println()
	fmt.Println()
	for i,c := range bytes{

		r,_ :=utf8.DecodeRune(bytes)
		fmt.Printf("%d  %c %x \n",i,r,c)
	}
	for i ,ch := range []rune(str){
		fmt.Printf("%d: %c  ",i,ch)
	}

	str2 := "123 我按時 的發ad fg票 是否 adfg 發 發生a f發 的sj df"
	sps   := strings.Split(str2," ")
	sps = strings.Fields(str2)
	var isContact  =  strings.Contains(str2,"你們")
	fmt.Println(sps)
	fmt.Println(isContact)
}

6、 golang中的結構體和繼承

7、 golang中的介面

8、 golang中的空interface

類似於java中的object,空interface(interface{})不包含任何的method,正因為如此,所有的型別都實現了空interface。空interface對於 描述起不到任何的作用(因為它不包含任何的method),但是空interface在我們需要儲存任意型別的數值的時候相當有用,因為它可以儲存任意型別的數值。它有點類似於C語言的void*型別。

一個函式把interface{}作為引數,那麼他可以接受任意型別的值作為引數,如果一個函式返回interface{},那麼也 就可以返回任意型別的值。是不是很有用啊!

9、結構體中可以定義欄位,但介面不行

structs與interfaces不能具有相同的API,因為interfaces無法定義欄位。這個問題並算很大,因為可以在介面中定義getter和setter方法,雖然這有點混亂。 eg:

10、Public和Private命名

Golang將Python的public和private方法命名方案做了進一步發展。當我最初發現以大寫字母開頭的函式、結構體是public,而小寫開頭的則是private的時候, 感覺不可思議,但我很享受這種語法。

type PublicStructName struct {} //public 外部能呼叫
type privateStructName struct {} // 私有 結構體,僅內部函式能呼叫

最後

閱讀更多

相信自己,沒有做不到的,只有想不到的

在這裡獲得的不僅僅是技術!