跟著老貓來搞GO,集跬步而致千里

程式設計師老貓發表於2021-11-01

上次部落格中,老貓已經和大家同步瞭如何搭建相關的GO語言的開發環境,相信在車上的小夥伴應該都已經搞定了環境了。那麼本篇開始,我們就來熟悉GO語言的基礎語法。本篇搞定之後,其實期待大家可以和老貓一樣,能夠寫出一些比較簡單的程式碼片段。

變數定義

變數的定義其實也是比較簡單的,主要就是利用var關鍵字+變數的名稱+變數的型別。例子如下:

func variableDefinition()  {
	var a int
	var s string
	fmt.Printf("%d %q\n",a,s)
}

大家可以比較容易地發現go語言的定義方式比較特別,其變數名稱是放在型別之前的。其實個人認為這也是和人的思考方式有關係,有的人在寫變數的時候先想到的是名稱再想到是型別,而有些人先想到是型別,然後是名稱。這裡需要注意的是,如果我們不賦予相關的初始值的時候,go語言其實會自帶初始化的值,以上的程式通過main函式執行完畢之後,就會輸出

0 ""

大家可以試著去寫一下,然後執行一下,至於其中的佔位符,以及為什麼這麼寫,這個大家可以查閱一下相關的手冊。這些屬於死知識。

再看下面比較騷的定義,針對多個變數同時賦值的時候,可以這樣寫

func variableInitialValue(){
	var a,b int = 3,4
	var s string = "abc"
	fmt.Println(a,b,s)
}

演化的再再騷一些,其實可以直接連變數的名稱都不寫,不同型別的變數可以寫在同一行,GO語言會自動識別變數的型別是什麼。

func variableDeduction(){
	var a,b,c,d = 3,4,"666",true
	fmt.Println(a,b,c,d)
}

在GO語法裡面我們們甚至連var都不寫,直接用:=的方式去初始化變數,具體如下。

func variableShorter(){
	a,b,c,d := 3,4,"666",true
	fmt.Println(a,b,c,d)
}

但是這種寫法只能夠在方法體內去寫,如果在存在包內作用變數,那麼此時就不能這麼寫必須還是老老實實的用var關鍵字,或者用var關鍵字外加括號的形式。程式碼如下:

var (
	aa = 1
	bb = "ktdaddy"
	cc = true
)

func variableDefinition()  {
	var a int
	var s string
	fmt.Printf("%d %q\n",a,s)
}

但是以上這些定義有個注意點,無論如何定義,定義好的變數必須得在後續中用到,否則會報語法錯誤。

以上差不多是所有GO的變數的定義了,我們們來做一下總結。使用var關鍵字定義變數

  • 變數定義var a,b,c bool
  • 變數初始化var a,b string = "hello","world"
  • 變數可以定義在函式內,也可以定義在包內
  • 當然還以用var()集中來進行變數定義。
  • 編譯器可以自動決定型別 var a,b,c,d = 3,4,"666",true
  • 函式內可以使用標記來進行變數定義 a,b,c,d := 3,4,"666",true,但是無法在包內使用,只能在函式內

基本資料型別

上面我們介紹了一下變數的定義,但是我們的變數又有哪些內建變數型別呢?目前主要分為以下大類。

主要看上圖的相關的解釋說明,至於比較詳細的地方,我們們可以在後續使用的過程中慢慢去體會。

常量和列舉

上面和大家介紹了變數的定義方式主要是用var關鍵字進行定義,其實我們的常量的定義方式也和變數的定義方式有所類似,我們常量的定義方式主要是用const。我們來看一下例子:

func constDefinition(){
	const name  string = "abc" //型別方式
	const name2 = "abc" //省略型別的方式
	const name3,age  = "abc",19 //同時定義多個變數
	const (
		name4 = "abc"
		nickname = "bcd"
		age2 = 23
	) //集合一起定義
}

接下來我們再看一下列舉型別。在GO語言中,列舉型別其實是一組特殊的常量。不像java中有專門的enum關鍵字,我們來看一下具體的DEMO:

func enums(){
	const (
		cpp = 0
		java = 1
		golang = 2
		python = 3
	)
	fmt.Println(cpp,java,java,golang,python)
}

這樣使用即可,當然還有一種比較簡潔的寫法,如下

func enums(){
	const (
		cpp = iota
		java 
		golang 
		python
	)
	fmt.Println(cpp,java,java,golang,python)
}

如果使用關鍵字"iota"的話,後面的值就是一個自增的值。分別為0,1,2,3。再如下相關儲存大小的換算

func storage(){
	const (
		b = 1<<(10*iota)
		kb
		mb
		gb
		tb
		pb
	)
	fmt.Println(b,kb,mb,gb,tb,pb)
}

大家不妨去試一下。

上面,我們把所有的變數以及常量的定義和大家分享了一下,大家可以跟著上面的demo自己也手動寫一下,接下來我們們就開始進入到程式控制流程的語法中來了。

條件語句

if條件語句

因為比較簡單,而且這種語法的熟悉其實是一種記憶的過程,也沒有什麼為什麼好說,所以我們們還是直接上程式碼。

func ifTest(v int)  int{
	if v<100 {
		return 50
	}else if v>100 && v<300{
		return 60
	}else{
		return 0
	}
}

這個主要想說明一下的就是if的條件裡面寫法上是不需要括號的。

我們使用這個條件語句寫一個小的DEMO,這個DEMO主要是從檔案中讀取內容。

func main() {
	const filename  = "abc.txt"
	contents,error := ioutil.ReadFile(filename)
	if error != nil {
		fmt.Println(error)
	}else {
		fmt.Printf("%s\n",contents)
	}
}

這樣呢就可以讀取檔案abc.txt中的內容了,當然這個大家最好試一下,語法上的東西還是得自己多動手才能掌握。我們再看另外一種比較騷的寫法,我們甚至可以直接把流程寫到我們的If條件中。具體如下:

func main() {
	const filename  = "abc.txt"
	if contents,error := ioutil.ReadFile(filename);error !=nil{
		fmt.Println(error)
	}else {
		fmt.Printf("%s\n",contents)
	}
}

上面有兩個點。

  • if的條件裡是可以賦值的
  • if的條件裡賦值的變數作用域就在這個If語句裡

switch條件語句

同樣的我們也是直接看一下程式碼吧。

func switchTest(a,b int,op string) int{
	var result int
	switch op {
	case "+":
		result = a + b
	case "*":
		result = a * b
         fallthrough
	case "/":
		result = a / b
	case "-":
		result = a - b
	default:
		panic("unsupport operate" + op)
	}
	return result
}

大家比較會發現,我上面寫的語句中居然沒有break語句。其實go語言還是比較人性的,怕每個語句都寫一個break,所以GO的switch會自動break,除非使用fallthrough。大家可以對panic有點疑問,其實這個是一種拋錯行為,類似於java中的throw Exception。到此呢,我們的條件語句就和大家同步完了,非常簡單,但是要練習一下。

迴圈語句

for語句

我們來直接看程式碼,具體的DEMO如下:

sum :=0
for i:=1;i<100;i++{
	sum +=i
}

//再例如,省略開始,我們寫一個整形轉二進位制的
func convertToBin(n int)  string{
	result := ""
	for ; n>0 ; n /=2 {
		lsb :=n%2
		result = strconv.Itoa(lsb) + result
	}
	return result
}
//再例如,省略起始,我們一行行讀取一個文字中的資訊,並且將其列印出來,此處也是相當於while
func printFile(fileName string)  {
	file,err := os.Open(fileName)
	if err !=nil {
		panic(err)
	}
	scanner := bufio.NewScanner(file)
	for scanner.Scan(){
		fmt.Println(scanner.Text())
	}
}
//甚至我們們可以寫成死迴圈,這樣的話就相當於while
for {
    fmt.Println("abc")
}

以上有兩個注意點:

  • for的條件裡不需要括號
  • for的條件裡可以省略初始條件,結束條件,遞增表示式

寫在最後

完成以上基礎語法的學習之後呢,其實,我們就可以寫出一些稍微複雜一些的程式碼片段了。上面的例子感興趣的小夥伴也可以動手去寫一下,其實學習一門程式語言沒有什麼好的辦法,最最關鍵的還是得多多動手才能很好地去熟悉。我是老貓,更多內容,歡迎大家搜尋關注老貓的公眾號“程式設計師老貓”。

相關文章