[筆記] 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") 
  |