[筆記] Golang 基礎
基本特性
- 泛用的程式語言
- 強調效能
- 易學
- 垃圾回收 ( 內存管理 )
- 編譯語言 ( Compiled language )
安裝
下載地址 : Golang 官方網址
流程
- 撰寫程式
1 2 3 4 5 6 7
| package main
import "fmt"
func main() { fmt.Println("Hello") }
|
建置 ( build ) : go build <檔名>.go
執行程式 : 直接在終端機打上 ./
+ .exe
檔的檔名
Workspaces
- src : 放置原始碼檔案
- pkg : 放置使用到的函式庫
- bin : 放置執行檔
資料、資料型態、變數
資料型態
資料型態轉換
type(變數)
: 以資料型態把變數括起來,例如 :
變數宣告
1 2 3
| var <變數名稱> <資料型態名稱> var <變數名稱> = 100 <變數名稱> := 100
|
資料型態重命名
1 2
| type IDnum int var pid IDnum
|
變數可視範圍 ( Variable Scope )
GO 裡面是以 {}
來分隔區塊的
- Universe block : 整個 GO 的程式碼
- Package block : package 內的程式碼
- File block : 檔案內的程式碼
- if、for、switch… : 語法內的程式碼
- switch、select 內的子句 : 子句內的程式碼
基本輸入與輸出
載入內建封包
從終端介面輸入
1 2 3
| fmt.Scanln(&變數名稱, &變數名稱, ...) fmt.Scan(&變數名稱, &變數名稱, ...) fmt.Scanf("變數格式,EX : %d", &變數名稱)
|
&變數名稱
: 取得變數的指標 ( Pointer )
印出到終端介面
1 2 3
| fmt.Println(資料, 資料, ...) fmt.Print(資料, 資料, ...) fmt.Printf("變數格式,EX : %d", 變數名稱)
|
指標 ( Pointer )
&
: 傳回變數或函式的地址
*
: 傳回此地址的值
1 2 3 4 5 6
| var x int = 1 var y int var ip *int
ip = &x y = *ip
|
new()
: 這個函式用來創建變數,並給予變數指標
1 2
| ptr := new(int) *ptr = 3
|
結構控制
if
for loops ( Go 沒有 while,for 是唯一的循環語句 )
1 2 3
| for <初始值>;<結束值>;<更新值> { <待執行程式> }
|
1 2 3 4 5
| <初始值> for <結束值> { <待執行程式> <更新值> }
|
switch
1 2 3 4 5 6 7 8
| switch <變數> { case <變數為此執行此行>: <待執行程式> case <變數為此執行此行>: <待執行程式> default: <待執行程式> }
|
1 2 3 4 5 6 7 8
| switch { case <條件>: <待執行程式> case <條件>: <待執行程式> default: <待執行程式> }
|
複合型別
Arrays
- 固定空間的元素集合
- 以
[]
宣告與表示
- 索引從 0 開始
- 初始值為 0 或空字串
1 2 3
| var x [5]int x[0] = 2 fmt.Printf(x[1])
|
1
| var x [5]int = [5]{1, 2, 3, 4, 5}
|
1
| x := [...]int {1, 2, 3, 4}
|
1 2 3 4 5
| x := [3]int {1, 2, 3}
for i, v range x { fmt.Printf("ind %d, val %d", i, v) }
|
- 在 for loop 使用
range
,range
會回傳兩個數值,索引值與此索引內的值
Slices
- 可動態的增加空間,不需像 array 一樣指定大小
由三個元件組成
- Pointer : 指向一個 array 的指標
- Length : 資料實際長度,
len()
可傳回 Slice 的長度
- Capacity : 容量,
cap()
可傳回 Slice 的容量
1 2 3
| arr := [...]string {"a", "b", "c", "d", "e", "f", "g"} s1 := arr[1:3] s2 := arr[2:5]
|
1 2
| sli1 = make([]int, 10) sli2 = make([]int, 10, 15)
|
1 2
| sli = make([]int, 0, 3) sli = append(sli, 100)
|
- 使用
append()
增加 Slice 內的元素
Hash Tables
- Key 和 value
優點 :
- 較快的搜尋速度 : 比起 list 一個一個找快很多
- 有意義的 Key : Key 非整數,是可以命名的字串,在撰寫程式時較容易辨別
缺點 :
- 可能會有碰撞 : 兩個 Key hash 到同個位置,碰撞會使程式慢上一些,但發生機率極低
Maps
1 2 3 4 5
| var idMap1 map[string]int idMap2 = make(map[string]int) idMap3 := map[string]int { "joe" : 123 }
|
1
| fmt.Println(idMap["joe"])
|
1 2
| id, p := idMap["joe"] fmt.Println(len(idMap))
|
- id 為 value,p 為是否存在此 Key,存在為 true
len()
可查看此 Map 有多少鍵值對
1 2 3
| for key, val := range idMap { fmt.Println(key, val) }
|
Structs
1 2 3 4 5 6
| type struct Person { name string addr string phone string } var p1 Person
|
1
| p1 := Person(name : "joe", addr : "a st.", phone : "123")
|
1 2
| p1.name = "joe" x = p1.addr
|
協定與格式
1 2 3
| import "net/http"
http.Get(www.uci.edu)
|
- 使用 HTTP 協定,GET、POST、PUT…等等
1 2 3
| import "net"
net.Dial("tcp", "uci.edu:80")
|
- 使用於 TCP/IP 連線與撰寫 socket 程式
JSON ( JavaScript Object Notation )
- 是一種屬性鍵值對,類似 struct 或 map
- 鍵值可以是任意基本資料型態,Bool、Number、String、Array…等等
- unicode 編碼
- RFC 之一
- 可以結合多種資料型態
1
| p1 := Person(name : "joe", addr : "a st.", phone : "123")
|
1 2 3 4 5
| { "name":"joe", "addr" : "a st.", "phone" : "123" }
|
1 2 3
| import "encoding/json"
barr, err := json.Marshal(p1)
|
1 2 3
| var p2 Person
err := json.Unmarshal(barr, &p2)
|
- 將 JSON 格式轉換成 go object 放進
p2
- 會自動適應 Person 的各項屬性,若無會回傳 err
File
ioutil
1 2 3
| import "ioutil"
data, e := ioutil.ReadFile("test.txt")
|
- ReadFile 可以讀取檔案內容,不須開啟與關閉檔案,如果檔案過大可能會造成錯誤
1 2 3
| data = "Hello, world"
err := ioutil.WriteFile("outfile.txt", data, 0777)
|
- WriteFile 會創建一個檔案並寫入資料後關閉,
0777
為權限
os
1 2 3 4 5 6 7 8
| import "os"
f, err := os.Open("dt.txt")
barr := make([]byte, 10) nb, err := f.Read(barr)
f.Close()
|
1 2 3 4 5
| f, err := os.Create("outfile.txt")
barr := []byte{1, 2, 3} nb, err := f.Write(barr) nb, err := f.WriteString("Hi")
|