go學習筆記:2.變數、型別、常量
基本型別
1.基本型別列表
型別 長度 說明
bool 1 true/false,預設false, 不能把非0值當做true(不用數字代表true/false)
byte 1 uint8 別名
rune 4 int32別名。 代表一個unicode code point
int/unit 一來所執行的平臺,32bit/64bit
int8/uint8 1 -128 ~ 127; 0 ~ 255
int16/uint16 2 -32768 ~ 32767; 0 ~ 65535
int32/uint32 4 -21億 ~ 21億, 0 ~ 42億
int64/uint64 8
float32 4 精確到7位小數,相當於c的float
float64 8 精確到15位小數,相當於c的double
complex64 8
complex128 16
uintptr 足夠儲存指標的32位、64位整數,指標(可以存指標的整數型)
array 值型別,陣列
struct 值型別,結構體
string 值型別,字串型別,常用
slice 引用型別,切片
map 引用型別,字典
channel 引用型別,通道
interface 介面型別,介面
function 函式型別,函式
2.型別轉換
不支援隱式型別轉換,必須進行顯式型別轉換
轉換隻發生在兩種互相相容的型別之間: 各類int不允許相互賦值或操作,不然會在編譯時報錯
<type>(expression)
示例
複製程式碼程式碼如下:
package main
import "fmt"
func main(){
a := 0x1234
b := 1234.56
c := 256
fmt.Printf("%x\n", uint8(a))
fmt.Printf("%d\n", int(b))
fmt.Printf("%f\n", float64(c))
}
結果
複製程式碼程式碼如下:
34
1234
256.000000
3.類型別名
type t_str string
var b t_str = "a str"
4.型別預設值
宣告不賦值,型別零值,非空值,而是聲明後的預設值
bool: false
integers: 0
floats: 0.0
string: ""
pointers,functions,interfaces,slices,channels,maps: nil
保留字
break case chan const continue
default defer else fallthrough for
func go goto if import
interface map package range return
select struct switch type var
變數
1.變數宣告
//第一種,指定變數型別,聲明後若不賦值,使用預設值
var v_name v_type
v_name = value
//第二種,根據值自行判定變數型別
var v_name = value
//第三種,省略var, 注意 :=左側的變數不應該是已經宣告過的,否則會導致編譯錯誤.
v_name := value
e.g.
var a int = 10
var b = 10
c : = 10
示例:
package main
var a = 1234
var b string = "hello"
var c bool
func main(){
println(a, b, c)
}
結果:
1234 hello false
2.多變數宣告:
//型別相同多個變數, 非全域性變數
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
var vname1, vname2, vname3 = v1, v2, v3 //和python很像,不需要顯示宣告型別,自動推斷
vname1, vname2, vname3 := v1, v2, v3 //出現在:=左側的變數不應該是已經被宣告過的,否則會導致編譯錯誤
//型別不同多個變數, 全域性變數, 區域性變數不能使用這種方式
var (
vname1 v_type1
vname2 v_type2
)
示例:
複製程式碼程式碼如下:
package main
var x, y int
var ( //這種只能出現在全域性變數中,函式體內不支援
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//這種不帶宣告格式的只能在函式體中出現
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}
結果:
複製程式碼程式碼如下:
0 0 0 false 1 2 123 hello 123 hello
注意:
A.多變數賦值時,將先行計算所有左側變數的值,再進行賦值
i := 0
i, l[i] = 1, 2
//get i = 1, l[0] = 2
sc[0], sc[0] = 1, 2
//get sc[0] = 2
B.垃圾桶_
複製程式碼程式碼如下:
func test()(int, string) {
return 123, "abc"
}
a, _ := test()
C.已宣告但是沒有使用的變數會在編譯階段報錯,較Python 更為嚴格
常量
常量可以是字元,字串,布林或數字
常量賦值是編譯期的行為
1.常量宣告
在編譯階段就能確定下來的值,在執行時無法改變該值
常量可以定義為數值、布林值或字串等型別
const constantName = value
const Pi float32 = 3.1415926
const c_name [type] = value
const c_name1, c_name2 = value1, value2
const (
c_name1 = vluae1
c_name2 = value2
)
=右側,必須為常量或常量表達式,如果使用到了函式,必須為內建函式(編譯期行為)
const i = 10000
說明:
A.常量必須是編譯期能確定的Number(char/integer/float/complex)、String和bool
B.在定義常量陣列時,如果不提供初始化值,則表示與上行常量型別,值,完全相同
const (
a = "abc"
b
)
//則 b = "abc"
C.常量可以用len(), cap(), unsafe.Sizeof()常量計算表示式的值. 常量表達式中,函式必須是內建函式,否則編譯不過
package main
import "unsafe"
const (
a = "abc"
b = len(a)
c = unsafe.Sizeof(a)
)
func main(){
println(a, b, c)
}
結果: abc 3 16
列舉
iota,特殊常量,可以認為是一個可以被編譯器修改的常量
在每一個const關鍵字出現時,被重置為0,然後再下一個const出現之前,每出現一次iota,其所代表的數字會自動增加1
不提供初始值,則表示使用上一行的表示式
1.宣告:
iota生成從0開始的自動增長列舉值,意味著,多一個列舉值,iota+=1,無論是否使用
基本語法
const (
a = 1
b = 2
)
const (
a = iota //0
b //1
c //2
)
const (
_ = iota
a //1
b //2
)
iota用法
func main() {
const (
a = iota //0
b //1
c //2
d = "ha" //獨立值,iota += 1
e //"ha" iota += 1
f = 100 //iota +=1
g //100 iota +=1
h = iota //7,恢復計數
i //8
)
}
const (
x = iota // 0
y = iota // 1
z = iota // 2
w //省略,預設和前面一樣字面值 w = iota, 即3
)
const v = iota //遇到const關鍵字,iota重置
注意: 每行的變數數必須一致 const ( A, B = iota, iota C, D E, F )
func main() {
println(A,B,C,D,E,F)
}
//結果: 0 0 1 1 2 2 【各自增長】
運算子
Go運算子全部是從左到右結合的
不支援運算子過載
優先順序 運算子 說明
高 * / % << >> & &^(AND NOT)
+ - ! ^
== != < <= > >=
<- channel運算子
&&
低 ||
在go中,++ --為語句,而非表示式
複製程式碼程式碼如下:
package main
func main(){
i := 1
i ++
println(i)
b := i
println(b)
//syntax error: unexpected ++, expecting semicolon or newline or }
//c := i++
//意味著, ++/--不能出現在等號右側
}
指標
Go保留了指標, *T表示T對應的指標型別
如果包含包名, 則應該是 *.T
代表指標型別的符號 '*' 總是和型別放在一起,而不是緊挨著變數名
同樣支援指標的指標**T
1.宣告
var a, b *int
2.說明
複製程式碼程式碼如下:
操作符&取變數地址,用*透過指標變數間接訪問目標物件
預設值是nil,沒有NULL常量
不支援指標運算,不支援‘->'預算福,直接'.'選擇符操作指標目標物件成員
可以在unsafe.Pointer和任意型別指標間進行轉換
可以將unsafe.Pointer轉換為uintptr,然後變相做指標運算,uintptr可以轉換為整數
3.示例
package main
import "fmt"
type User struct {
Id int
Name string
}
func main(){
i := 100
var p *int = &i //取地址
println(*p) //取值
up := &User{1, "Jack"}
up.Id = 100 //直接取只針對想成員
fmt.Println(up)
u2 := *up //拷貝物件
u2.Name = "Tom"
fmt.Println(up, u2)
}
4.結果:
100
&{100 Jack}
&{100 Jack} {100 Tom}
分組宣告
複製程式碼程式碼如下:
import (
"fmt"
"os"
)
const (
i = 100 //首行必須有常量表達式
pi = 3.1415
)
var ( //全域性變數可用,函式體內不支援
i int
pi float32
)