Go語言入門教程(省略與C相同的部分語言規則)

教程網址:https://www.runoob.com/go/go-tutorial.html

Go 語言語法與 C 相近,有C的基礎的話入門很簡單。下面的筆記直接去掉了跟C語言重疊的部分規則。

Go語言教程

第一個 Go 程序 hello.go(Go 語言源文件的擴展是 .go),代碼如下:

package main
import "fmt"

func main() {  
    fmt.Println("Hello, World!")
}

注意 { 不能單獨放一行

運行go程序的命令

go run hello.go 

也可以先build後運行

go bulid hello.go  #編譯生成二進制文件hello
./hello   #運行二進制文件

Go 語言結構

  1. package main 定義了包名。你必須在源文件中非註釋的第一行指明這個文件屬於哪個包,如:package main。package main表示一個可獨立執行的程序,每個 Go 應用程序都包含一個名爲 main 的包。
  2. import "fmt" 引入fmt 包,fmt 包實現了格式化 IO(輸入/輸出)的函數。
  3. func main() 是程序開始執行的函數。每一個可執行程序所必須包含main 函數,一般來說都是在啓動後第一個執行的函數(如果有 init() 函數則會先執行該函數)。
  4. 註釋方式跟C/C++相同,用 // 或 /*… */
  5. fmt.Println(…) 輸出字符串,並在最後自動增加換行字符 \n,等同於fmt.Print(“hello, world\n”)
  6. 以一個大寫字母開頭的標識符(包括常量、變量、類型、函數名、結構字段等等)對象,如:Group1可以被外部包的代碼所使用(客戶端程序需要先導入這個包),這被稱爲導出(像面嚮對象語言中的 public);標識符如果以小寫字母開頭,則對包外是不可見的,只能在包內使用(像面嚮對象語言中的 protected )。

Go 語言基礎語法

與C/C++基本相同,建議多用空格使語句更美觀。

Go 語言數據類型

與C/C++一樣,在 Go 編程語言中,數據類型用於聲明函數和變量。數據類型的出現是爲了把數據分成所需內存大小不同的數據,編程的時候需要用大數據的時候才需要申請大內存,就可以充分利用內存。

布爾型bool、整型 int 和浮點型 float32、float64 等等。

Go 語言變量

  1. 聲明變量時指定變量類型

    var identifier type   //聲明一個type類型的變量identifier
    identifier = value    //給變量賦值
    var a string = "Runoob"
    
    var identifier1, identifier2 type	//聲明兩個type類型的變量identifier1、identifier2
    var b, c int = 1, 2
    
  2. 聲明變量時不給定變量類型,讓編譯器根據值自行判定變量類型

    var v_name = value
    var b = true
    
  3. 極致偷懶:聲明變量時不僅不給定變量類型,還把var省略掉

    v_name := value
    a := 1   //注意使用:=時左邊必須聲明新的變量,不能用來給已聲明的變量賦值
    s := "fight"
    

    看起來的話使用這種方法最簡潔,但是它只能用在函數體中,用來聲明局部變量,不能用來聲明全局變量。聲明全局變量還是得用前面兩種。

聲明瞭一個局部變量卻沒有在相同的代碼塊中使用它,會得到編譯錯誤。而全局變量是允許聲明但不使用。

go語言允許並行賦值,也就是類似 var b , c = 1 , true ,因此go函數可以返回多個返回值(像python一樣)。

Go 語言常量

常量是指不會被改變的量。

const b string = "abc"  //顯式類型定義
const b = "abc"		//隱式類型定義
const (   //枚舉
    Unknown = 0
    Female = 1
    Male = 2
)

iota,特殊常量,可以認爲是一個可以被編譯器修改的常量。iota 在 const關鍵字出現時將被重置爲 0(const 內部的第一行之前),const 中每新增一行常量聲明將使 iota 計數一次(iota 可理解爲 const 語句塊中的行索引)。

Go 語言運算符&條件語句

跟C/C++一模一樣

Go 語言循環語句

for循環有三種形式:

for init; condition; post { }
for condition { }  //跟while一樣
for { }  //無限循環

舉實例代碼是最簡潔明瞭的。

for 循環的 range 格式可以對 slice、map、數組、字符串等進行迭代循環。格式如下:

for key, value := range oldMap {
    newMap[key] = value
}

計算1~10的數字之和

package main

import "fmt"

func main() {
        sum := 0
        for i := 0; i <= 10; i++ {
                sum += i
        }
        fmt.Println(sum)
}

For-each range 循環

這種格式的循環可以對字符串、數組、切片等進行迭代輸出元素。

package main
import "fmt"

func main() {
        strings := []string{"google", "runoob"}
        for i, s := range strings {
                fmt.Println(i, s)
        }


        numbers := [6]int{1, 2, 3, 5}
        for i,x:= range numbers {
                fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
        }  
}

Go 語言函數

Go 語言函數定義格式如下:

func function_name( [parameter list] ) [return_types] {
   函數體
}

實例

/* 函數返回兩個數的最大值 */
func max(num1, num2 int) int { //傳參時不用寫var
   /* 聲明局部變量 */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result
}

上述的是值傳遞,下面的是引用傳遞

/* 定義交換值函數*/
func swap(x *int, y *int) {
   var temp int
   temp = *x    /* 保持 x 地址上的值 */
   *x = *y      /* 將 y 值賦給 x */
   *y = temp    /* 將 temp 值賦給 y */
}

Go 語言變量作用域

跟C/C++一模一樣

Go 語言數組

Go 語言數組聲明需要指定元素類型及元素個數,語法格式如下:

var variable_name [SIZE] variable_type

以上爲一維數組的定義方式。例如以下定義了數組 balance 長度爲 10 類型爲 float32:

var balance [10] float32	//[]中必須填數字

數組初始化:

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0} //初始化[]中可以不填數字,讓編譯器自行判斷

訪問數組元素

var salary float32 = balance[3]

向函數傳遞數組

func getAverage(arr []int, size int) float32
{
   var i int
   var avg, sum float32  
   for i = 0; i < size; ++i {
      sum += arr[i]
   }
   avg = sum / size
   return avg;
}

Go 語言指針

一個指針變量指向了一個值的內存地址。

以下是有效的指針聲明(都是空指針 nil ):

var ip *int        /* 指向整型*/
var fp *float32    /* 指向浮點型 */

指針使用流程:

  • 定義指針變量。
  • 爲指針變量賦值。
  • 訪問指針變量中指向地址的值。
package main

import "fmt"

func main() {
   var a int= 20   /* 聲明實際變量 */
   var ip *int        /* 聲明指針變量 */

   ip = &a  /* 指針變量的存儲地址 */

   fmt.Printf("a 變量的地址是: %x\n", &a  )
   fmt.Printf("ip 變量儲存的指針地址: %x\n", ip )	/* 指針變量的存儲地址 */
   fmt.Printf("*ip 變量的值: %d\n", *ip )	 /* 使用指針訪問值 */
}

Go 語言結構體

直接上實例

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}

func main() {
    var Book1 Books        /* 聲明 Book1 爲 Books 類型 */
    /* book 1 描述 */
    Book1.title = "Go 語言"
    Book1.author = "www.runoob.com"
    Book1.subject = "Go 語言教程"
    Book1.book_id = 6495407
    
    // 創建一個新的結構體
    var Book2 Books = Books{"Go 語言", "www.runoob.com", "Go 語言教程", 6495407}
    // 也可以使用 key => value 格式 , 忽略的字段爲 0 或 空
   	var Book3 Books = Books{title: "Go 語言", author: "www.runoob.com"} 
}

訪問結構體成員也是跟C/C++一樣

結構體.成員名"

你可以定義指向結構體的指針類似於其他指針變量,格式如下:

var book_pointer *Books

以上定義的指針變量可以存儲結構體變量的地址。查看結構體變量地址,可以將 & 符號放置於結構體變量前:

book_pointer = &Book1

使用結構體指針訪問結構體成員,使用 “.” 操作符:

book_pointer.title

那這跟Book1.title好像一樣啊,似乎是沒什麼意義。

Go 語言切片(Slice)

與數組相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。

你可以聲明一個未指定大小的數組來定義切片:

var identifier []type

或使用make()函數來創建切片:

var slice1 []type = make([]type, len)  //len是切片的初始長度
slice1 := make([]type, len) //簡寫版本

切片初始化

s :=[] int {1,2,3 } //[]表示是切片類型,{1,2,3}初始化值依次是1,2,3.其cap=len=3
s := arr[startIndex:endIndex] //將數組arr中從下標startIndex到endIndex-1 的元素創建爲一個新的切片

len() 方法獲取切片長度:len(s)

截取部分切片,類似python,比如 s[1:3] 代表第二個元素到第三個元素(注意包括索引下限的元素,不包括索引上限的元素)。

拷貝切片的 copy 方法和向切片追加新元素的 append 方法

package main

import "fmt"

func main() {
   var numbers []int
   numbers = append(numbers, 1)   /* 向切片添加一個元素 */
   /* 創建切片 numbers1 是之前切片的兩倍容量*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)
   copy(numbers1,numbers)/* 拷貝 numbers 的內容到 numbers1 */
}

Go 語言範圍(Range)

Go 語言中 range 關鍵字用於 for 循環中迭代數組(array)、切片(slice)、通道(channel)或集合(map)的元素。在數組和切片中它返回元素的索引和索引對應的值,在集合中返回 key-value 對。

package main
import "fmt"
func main() {
    //這是我們使用range去求一個slice的和。使用數組跟這個很類似
    nums := []int{2, 3, 4}
    sum := 0
    for _, num := range nums {
        sum += num
    }
    //在數組上使用range將傳入index和值兩個變量。上面那個例子我們不需要使用該元素的序號,所以我們使用空白符"_"省略了。

    //range也可以用在map的鍵值對上。
    kvs := map[string]string{"a": "apple", "b": "banana"}
    for k, v := range kvs {
        fmt.Printf("%s -> %s\n", k, v)
    }
    //range也可以用來枚舉Unicode字符串。第一個參數是字符的索引,第二個是字符(Unicode的值)本身。
    for i, c := range "go" {
        fmt.Println(i, c)
    }
}

Go 語言Map(集合)

Map 是一種無序的鍵值對的集合。Map 最重要的一點是通過 key 來快速檢索數據,可以像迭代數組和切片那樣迭代它。不過Map 是無序的,無法決定它的返回順序,這是因爲 Map 是使用 hash 表來實現的。

定義map

/* 聲明變量,默認 map 是 nil ,沒有初始化,不能用來存放鍵值對*/
var map_variable map[key_data_type]value_data_type

/* 使用 make 函數初始化map */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化 map,那麼就會創建一個 nil map。nil map 不能用來存放鍵值對

package main

import "fmt"

func main() {
    countryCapitalMap := make(map[string]string)/*創建集合 */

    /* map插入key - value對,各個國家對應的首都 */
    countryCapitalMap [ "France" ] = "巴黎"
    countryCapitalMap [ "Italy" ] = "羅馬"

    /*使用鍵輸出地圖值 */
    for country := range countryCapitalMap {
        fmt.Println(country, "首都是", countryCapitalMap [country])
    }

    /*查看元素在集合中是否存在 */
    capital, ok := countryCapitalMap [ "American" ]
    if (ok) {
        fmt.Println("American 的首都是", capital)
    } else {
        fmt.Println("American 的首都不存在")
    }
}

Go 語言遞歸函數

十分簡單,與C/C++相同

Go 語言類型轉換

十分簡單,也跟C/C++一樣

var num_int int = 5
var num_float32 float32
num_float32=float32(num_int)

剩餘部分省略

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章