筆記 - Golang 基礎

[筆記] Golang 基礎

基本特性

  • 泛用的程式語言
  • 強調效能
  • 易學
  • 垃圾回收 ( 內存管理 )
  • 編譯語言 ( Compiled language )

安裝

下載地址 : Golang 官方網址

流程

  1. 撰寫程式
1
2
3
4
5
6
7
package main //可執行的程式必須使用 main

import "fmt" //載入內建 fmt 封包,用來做基本輸出輸入

func main() {
fmt.Println("Hello")
}
  1. 建置 ( build ) : go build <檔名>.go

    • 建置完會出現 .exe
  2. 執行程式 : 直接在終端機打上 ./ + .exe 檔的檔名

Workspaces

  • src : 放置原始碼檔案
  • pkg : 放置使用到的函式庫
  • bin : 放置執行檔

資料、資料型態、變數

資料型態

  • int : 整數 ( int8、int16、int32、int64、uint8、uint16… )
  • float64 : 浮點數 ( float32、complex128 )

    1
    var x complex128 = complex(1, 2) //1 + 2i
  • string : "",字串

    • String package

      1
      2
      3
      4
      5
      6
      7
      8
      9
      Compare(a, b) //比較 a 與 b 字串
      Contains(str, substr) //判斷 str 是否包含 substr
      HasPrefix(str, prefix) //判斷 prefix 是否為 str 的前置字元
      Index(str, substr) //判斷 substr 在 str 第一個出現的位置
      Replace(str, old, new, n) //將 str 前 n 個 old 替換成 new
      TrimSpace(str) //去掉 str 頭尾的空白
      ToUpper(str) //轉成大寫
      ToLower(str) //轉成小寫
      ...
    • Strconv package

      1
      2
      3
      4
      5
      Atoi(str) //將字串轉換為數字
      Itoa(num) //將數字轉換為字串
      FormatFloat(f, fmt, prec, bitSize) //將浮點數轉換為字串
      ParseFloat(str, bitSize) //將字串轉換為浮點數
      ...
  • bool : 布林值

  • rune : '',字元,實際存放整數,所以印出來會是整數

    • Unicode package

      1
      2
      3
      4
      5
      6
      7
      8
      IsDigit(r rune) //判斷 r 是否為十進制數字
      IsSpace(r rune) //判斷 r 是否為空白
      IsLetter(r rune) //判斷 r 是否為字母
      IsLower(r rune) //判斷 r 是否為小寫
      IsPunct(r rune) //判斷 r 是否為符號
      ToUpper(r rune) //轉成大寫
      ToLower(r rune) //轉成小寫
      ...

資料型態轉換

type(變數) : 以資料型態把變數括起來,例如 :

1
int32(x)

變數宣告

1
2
3
var <變數名稱> <資料型態名稱> //宣告變數
var <變數名稱> = 100 //宣告變數並賦予值,自動判別型別
<變數名稱> := 100 //宣告變數並賦予值,自動判別型別
  • const

    1
    2
    3
    4
    5
    const <變數名稱> = 100 //const 宣告為固定值,不可改變
    const ( //多個 const 宣告
    <變數名稱> = "Hi"
    <變數名稱> = 1000
    )
  • iota

    1
    2
    3
    4
    const (
    <變數名稱> = iota //0
    <變數名稱> //1
    )

    iota 初始為 0,每次 const 都會讓 iota 初始化

資料型態重命名

1
2
type IDnum int //重命名後,int 還是可以用
var pid IDnum
  • 重命名後就可以使用新的資料型態名稱來宣告變數

變數可視範圍 ( Variable Scope )

GO 裡面是以 {} 來分隔區塊的

  • Universe block : 整個 GO 的程式碼
  • Package block : package 內的程式碼
  • File block : 檔案內的程式碼
  • if、for、switch… : 語法內的程式碼
  • switch、select 內的子句 : 子句內的程式碼

基本輸入與輸出

載入內建封包

1
import "fmt"

從終端介面輸入

1
2
3
fmt.Scanln(&變數名稱, &變數名稱, ...) //以換行為結束
fmt.Scan(&變數名稱, &變數名稱, ...) //以換行或空白為結束
fmt.Scanf("變數格式,EX : %d", &變數名稱) //跟 C 語言的用法一樣
  • &變數名稱 : 取得變數的指標 ( Pointer )

印出到終端介面

1
2
3
fmt.Println(資料, 資料, ...) //換行
fmt.Print(資料, 資料, ...) //不換行
fmt.Printf("變數格式,EX : %d", 變數名稱) //跟 C 語言的用法一樣

指標 ( Pointer )

  • & : 傳回變數或函式的地址
  • * : 傳回此地址的值
1
2
3
4
5
6
var x int = 1
var y int
var ip *int //ip is pointer to int

ip = &x //ip now points to x
y = *ip //y is now 1
  • new() : 這個函式用來創建變數,並給予變數指標
1
2
ptr := new(int)
*ptr = 3

結構控制

if

1
2
3
if <條件> { //條件沒有小括弧
<待執行程式>
}

for loops ( Go 沒有 while,for 是唯一的循環語句 )

1
2
3
for <初始值>;<結束值>;<更新值> {
<待執行程式>
}
1
2
3
4
5
<初始值>
for <結束值> { //類似 while
<待執行程式>
<更新值>
}

switch

1
2
3
4
5
6
7
8
switch <變數> { //Go 不需要 break
case <變數為此執行此行>:
<待執行程式>
case <變數為此執行此行>:
<待執行程式>
default:
<待執行程式>
}
1
2
3
4
5
6
7
8
switch { //switch 不用變數 tag 時,類似 if、else if
case <條件>:
<待執行程式>
case <條件>:
<待執行程式>
default:
<待執行程式>
}

複合型別

Arrays

  • 固定空間的元素集合
  • [] 宣告與表示
  • 索引從 0 開始
  • 初始值為 0 或空字串
1
2
3
var x [5]int
x[0] = 2
fmt.Printf(x[1]) //印出為 0
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 使用 rangerange 會回傳兩個數值,索引值與此索引內的值

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] //{"b", "c"}
s2 := arr[2:5] //{"c", "d", "e"}
  • s1、s2 為 Slices
1
sli := []int {1, 2, 3}
  • 宣告方法,也可以不給予初始值
1
2
sli1 = make([]int, 10) //len = cap = 10
sli2 = make([]int, 10, 15) //len = 10,cap = 15
  • 使用 make() 宣告
1
2
sli = make([]int, 0, 3)
sli = append(sli, 100) //len 會跟著增加
  • 使用 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) //以 make() 宣告
idMap3 := map[string]int { //宣告並給予值
"joe" : 123
}
  • 宣告
1
fmt.Println(idMap["joe"])
  • 使用
1
idMap["jane"] = 456
  • 新增
1
delete(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)
}
  • Map 在 for loop 的應用

Structs

  • 多種資料型態的集合
1
2
3
4
5
6
type struct Person {
name string
addr string
phone string
}
var p1 Person
  • 宣告
1
p1 := new(Person)
  • new() 宣告並初始化
1
p1 := Person(name : "joe", addr : "a st.", phone : "123")
  • 宣告並賦予值
1
2
p1.name = "joe"
x = p1.addr
  • 賦予值與使用

協定與格式

RFC ( Requests for Comments )

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")
  • struct
1
2
3
4
5
{
"name":"joe",
"addr" : "a st.",
"phone" : "123"
}
  • JSON,相當於上面的 struct
1
2
3
import "encoding/json"

barr, err := json.Marshal(p1)
  • 將 struct p1 轉換成 JSON 格式
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) //讀取檔案前 10 byte 進 barr,nb 為讀取多少 byte

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") //寫入字串
  • 創建檔案並寫入
tags: 筆記 程式語言 Golang
Author: Kenny Li
Link: https://kennyliblog.nctu.me/2019/07/22/Golang-basic/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.