教程網址: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 語言結構
- package main 定義了包名。你必須在源文件中非註釋的第一行指明這個文件屬於哪個包,如:package main。package main表示一個可獨立執行的程序,每個 Go 應用程序都包含一個名爲 main 的包。
- import "fmt" 引入fmt 包,fmt 包實現了格式化 IO(輸入/輸出)的函數。
- func main() 是程序開始執行的函數。每一個可執行程序所必須包含main 函數,一般來說都是在啓動後第一個執行的函數(如果有 init() 函數則會先執行該函數)。
- 註釋方式跟C/C++相同,用 // 或 /*… */
- fmt.Println(…) 輸出字符串,並在最後自動增加換行字符 \n,等同於fmt.Print(“hello, world\n”)
- 以一個大寫字母開頭的標識符(包括常量、變量、類型、函數名、結構字段等等)對象,如:Group1可以被外部包的代碼所使用(客戶端程序需要先導入這個包),這被稱爲導出(像面嚮對象語言中的 public);標識符如果以小寫字母開頭,則對包外是不可見的,只能在包內使用(像面嚮對象語言中的 protected )。
Go 語言基礎語法
與C/C++基本相同,建議多用空格使語句更美觀。
Go 語言數據類型
與C/C++一樣,在 Go 編程語言中,數據類型用於聲明函數和變量。數據類型的出現是爲了把數據分成所需內存大小不同的數據,編程的時候需要用大數據的時候才需要申請大內存,就可以充分利用內存。
布爾型bool、整型 int 和浮點型 float32、float64 等等。
Go 語言變量
-
聲明變量時指定變量類型
var identifier type //聲明一個type類型的變量identifier identifier = value //給變量賦值 var a string = "Runoob" var identifier1, identifier2 type //聲明兩個type類型的變量identifier1、identifier2 var b, c int = 1, 2
-
聲明變量時不給定變量類型,讓編譯器根據值自行判定變量類型
var v_name = value var b = true
-
極致偷懶:聲明變量時不僅不給定變量類型,還把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)