iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0

Background

對於變數的Type,能夠依據他們的特性分為兩種,分別為不可變的Static type以及可變的 Dynamic type

  • 靜態型別 Static type: 靜態型別是宣告變數時指定的型別,指的是一個變數的型別是永恆不變的,一般的普通變數只有靜態型別。
  • 動態型別 Dynamic type:動態型別是由介面型別變數賦值的具體值的型別來決定的,且除了動態型別外還有著動態值,這兩者彼此是相對應的。之所以被稱作動態型別,是因為介面型別的動態型別是會變化的。

而這章節主要就是介紹靜態型別,像是Boolean、String....等。

Boolean 布林

長度1bit,只能拿來當作true, false使用。

且在Go中Bool不能當作0或1使用(不能與數字作比較)

func main() {
	var b bool = false
	fmt.Println(b)
	if b == false{
		fmt.Println("b == false")
	}
}

運算後會得結果

false
b == false

Numbers 數字

數字可以根據長度與浮點數等因素有著各種不同的型態,像是int、float等。

Int

int8, int16, int32, int64

看名字就知道int後頭的數字代表的是長度bit

舉例來說8bit表示排列組合有著2的八次方⇒ 256種可能性,這也就是一個byte的大小,

因此256種可能性會從-128 ~ 127

下面有個錯誤的範例

package main

import (
	"fmt"
)

func main() {
	var a int8 = 128;
	fmt.Print(a)
}

運算後會得結果

# command-line-arguments
./variables.go:7:6: constant 128 overflows int8

uint

uint8, uint16, uint32, uint64

和int相同,但unsigned就是沒正負號意思。

如果是uint8則可以存在256種可能性0~255)

package main

import (
	"fmt"
)

func main() {
	var a uint8 = 128;
	fmt.Print(a)
}

運算後會得結果

128

float

float32, float64

通常都是拿精準度較高的float64做使用,

畢竟小數點會有誤差,使用float32誤差會比float64來得大。

此外,Go語言當中並沒有double

complex

complex64, complex128

複數,較少用到,不過內建有這種型別運算時十分方便。

package main

import (
	"fmt"
)

func main()  {
	var a complex64 = 2.4 + 3i
	fmt.Print(a)
}

運算後會得結果

(2.4+3i)

Char 字串

Go當中沒有char的型別。

通常以string 或是 rune 來代替

string

package main

import (
	"fmt"
)

func main() {
	var s string = "Hello World"
	fmt.Println(s)
}

運算後會得結果

Hello World

要注意的是,string中的字無法改變那怎麼辦?常見辦法有以下:

  • 用string[0:1]直接串文字
  • 用fmt.Sprint()串文字
  • 用Slice[] Append方法來接文字

由於string中的文字沒辦法改,要創新的變數來接收。

rune

rune意思是符號,簡單理解為UTF-8中的一個符號。

因為Go語言中預設使用UTF-8編碼。

UTF-8編碼中的每個字元長度不是固定,以8bit為基本長度,範圍為1~4個字節(1byte ~ 4bytes)

package main

import (
	"fmt"
)

func main()  {
	var r = []rune("0")
	fmt.Println(r)

	r = []rune("Hello World")
	fmt.Println(r)
}

運行後可得結果

[48]
[72 101 108 108 111 32 87 111 114 108 100]

長度怎麼算

長度到底是算符號數還是byte數

func main() {
	a := "哈囉 世界"
	fmt.Println(a)
	n := 0
	for range a{
		n++
	}
	fmt.Println(len(a))
	fmt.Println(n)
}

運行後可得結果

哈囉 世界
13
5

運行後可得知,以for range迭代出的長度,就是以bytes計算,

len()打印出的長度則是符號數,每個文字只算一個

byte

byte用法非常多,通常會配合Slice[]使用。

package main

import (
	"fmt"
)

func main()  {
	var b = []byte("0")
	fmt.Println(b)

	b = []byte("Hello World")
	fmt.Println(b)
}

運行後可得

[48]
[72 101 108 108 111 32 87 111 114 108 100]

這邊看起來byte好像跟rune很類似,但是

package main

import (
	"fmt"
)

func main()  {
	var a = []byte("哈囉 世界")
	fmt.Println(a)

	var b = []rune("哈囉 世界")
	fmt.Println(b)
}

運行後可得結果

[229 147 136 229 155 137 32 228 184 150 231 149 140]
[21704 22217 32 19990 30028]

與上述一樣,rune所記錄的是每個字元的記憶體位置而非bytes數。

C vs Go

這邊附上C語言與Go類型對比

C Go
char byte
singed char int 8
unsigned char uint8
short int16
unsigned short uint16
int int32
unsigned int uint32
long int32
unsigned long uint32
long long int int64
unsigned long long int uint64
float float32
double float64
size_t uint

雖然C語言的int固定長度為4,但Go語言自己類型的int與uint在32位與64位下分別對應長度為4與8個字節,這是需要注意的一點。

正規表示法 Regular Expression

最後則提及一下Go的正規表示法如何使用,它主要是透過內建包regexp來做實作,下面我們就舉個範例來說明

package main
import (
    "fmt"
    "regexp"
)
func main() {
    buf := "abc azc a1c aac aab a3c bac"

    reg1 := regexp.MustCompile(`a[0-9]c`)
    if reg1 == nil {
        fmt.Println("regexp err")
        return
    }
    
    result := reg1.FindAllStringSubmatch(buf, -1)
    fmt.Println("result = ", result)
}

運行後可得結果

result =  [[a1c] [a3c]]

上面範例我們是想透過正規表示法找出符合規則a number c 的所有結果,簡單的一個拋磚引玉讓大家去知道該如何引用正規表示法到Go當中,若對正規表示法有濃厚興趣者,可以到Wiki去了解更多相關資訊。

Summary

這章節主要是帶大家熟悉與宣告靜態的變數,那在下章節開始會著重於動態變數的宣告,這部分的使用會更加重要,尤其會凸顯與其他程式語言的不同,敬請期待。

Reference

https://zh.wikipedia.org/wiki/正则表达式


上一篇
Day4 Variable
下一篇
Day6 Array and Slice
系列文
fmt.Println("從零開始的Golang生活")30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言