[Golang] 資料型別 Data Types
Value vs Reference Types
信息
Go (Golang) Tutorial #13 - Pass By Value @ TheNet Ninjia
⚠️ 在 Go 中雖然都是 pass by value,但要不要使用 Pointer 端看該變數的型別,某些型別會表現得類似 pass by reference(Reference Types),例如 slice,這時候就可以不用使用 Pointer 即可修改原變數的值。
- 為什麼有些型別會表現的類似 pass by reference 可以參考「Array and Slice」的內容。
- Non-Pointer Values:string, int, float, boolean, array, struct
- Pointer Wrapper Values: slice, map, function
在 Golang 中,雖然所有資料結構都是 Pass by value,但當碰到 slices、maps、functions 時,雖然它還是會 copy 一份新的,但實際上,它 copy 的是一個 pointer,所以即使它依然是 copy by value,但對這個變數進行修改時,會修改到 pointer 背後實際所指稱到的記憶體位址,進而使得在操作這些資料結構時,會感覺像是 Pass by Reference:
func updateMenu(y map[string]float64) {
// y 一樣會時 copy 一個新的變數,但它是 pointer
// 實際上會指稱到背後相同的記憶體位址
y["cake"] = 2.99
}
func main() {
menu := map[string]float64{
"apple": 5.95,
"banana": 3.99,
}
updateMenu(menu)
fmt.Println(menu) // map[apple:5.95 banana:3.99 cake:2.99]
}
Concrete vs Interface Type
- concrete type 指的是可以被賦值的型別,例如,map, struct, int, string、一些自訂的 type。
- interface type 無法直接賦值的型別
Zero values
Zero values @ A Tour of Gp
在 GO 中,如果宣告了某個變數但沒有賦值的話,會使用 zero value:
Data Type | Zero Value |
---|---|
int | 0 |
float64 | 0 |
bool | false |
String | "" |
型別轉換(Type Conversion)
T(v)
這種方式,可以把 v
的值轉換成 T
這個型別。舉例來說:
func main() {
i := 42 // int
f := float64(i) // int 轉成 float64
u := uint(f) // float 64 轉成 uint
fmt.Println(i, f, u)
}
func main() {
hello := "Hello World"
helloSlice := string2ByteSlice(hello)
fmt.Println(helloSlice)
helloString := byteSlice2String(helloSlice)
fmt.Println(helloString)
}
// byte slice 轉成 string
func byteSlice2String(b []byte) string {
return string(b)
}
// string 轉成 byte slice
func string2ByteSlice(s string) []byte {
return []byte(s)
}
自定義資料型別
// 定義 cards 這個型別,它的本質是 slice of strings
type cards []string
// 定義 person 這個型別,它的本質是 struct
type person struct {
firstName string
lastName string
}
透過 function receiver 為該 type 添加方法
我們可以針對自定義的 data type 透過 function receiver 去建立方法,可以參考「[Golang] 函式 function」中的內容。