變數相當於記憶體中一個資料儲存空間的表示,像門牌號,通過門牌號找到房間(值)
- 變數的使用
- 定義變數
- 給變數賦值
- 使用變數
- 變數的使用三種方式
- 指定變數型別,宣告後不賦值,使用預設值
- 根據值自 推導變數型別
- :=的方式定義未曾定義過的變數
var i int //0
var num= 10.11
fmt.Println(num)
fmt.Println(reflect.TypeOf(num)) //10.11 float64
name := "zhangsan"
- 多變數的宣告 n1,n2,n3 := 1,”2”,3.3
- 一次性宣告多個全域性變數
var n1 = 100
var n2 = 101
var (
n3 = 1
n4 = "test"
)
var n1,name,n6 = 100, "test", 888
宣告變數: var 變數 型別
var a int
var num1 float32
初始化變數
var a int = 45
var b = 400 //宣告時候就賦值,忽略資料型別
給變數賦值
已經定義過 var num int //0
num = 12
Go中都是utf-8的編碼,所以btye存單個字母。
- byte是utf8的別名
- rune是int32的別名
4.1 整數型別
- 簡單的說,就是用於存放整數值的,比如 0, -1, 2345 等等
1個位元組8位,第一位表示符號,後七位表示值,-2的7次方到2的7次方-1
2個位元組8位,第一位表示符號,後15位表示值,-2的15次到2的15次方-1
2的8次方-1(0)
var a int = 8900
var b uint = 1
var c byte = 255
var d rune = 255
var num5 = 11.1
fmt.Printf("%T",num5) //64
1- 整型的使用細節
- Golang 各整數型別分:有符號和無符號,int uint 的大小和系統有關
- Golang 的整型預設宣告為 int 型
- 如何在程式檢視某個變數的位元組大小和資料型別
- Golang 程式中整型變數在使用時,遵守保小不保大的原則,即:在保證程式正確執行下,儘量使用佔用空間小的資料型別。【如:年齡 byte】
- Bit 計算機找那個最小的儲存單位,byte計算機基本儲存單元,1byte=8 bit
var n1 = 100
fmt.Printf("型別%T",n1)
var n2 int64 = 10
fmt.Printf("型別%T 佔的位元組數%d",n1,unsafe.Sizeof(n2))
//型別int 佔的位元組數8 64位8個位元組
4.2 小數型別/浮點型
小數型別就是用於存放小數的,比如 1.2 0.23 -1.911
var price float32 = 89.11
fmt.Println(price)
var num3 float32 = -123.0000901
var num4 float64 = -123.0000901
//-123.00009
//-123.0000901
1- 小數型別分類
- 關於浮點數在機器中存放形式的簡單說明,浮點數=符號位+指數位+尾數位說明:浮點數都是有符號的.
- 尾數部分可能丟失,造成精度損失。 -123.0000901
- 64位精度大於32位
2-浮點型使用細節
浮點型別有固定的範圍和欄位長度,不受具體 OS(作業系統)的影響
浮點型預設宣告為 float64 型別
1) 浮點型常量有兩種表示形式
十進位制數形式:如:5.12 .512 (必須有小數點)
科學計數法形式:如:5.1234e2 = 5.12 * 10 的 2 次方 5.12E-2 = 5.12/10 的 2 次方
2) 通常情況下,應該使用 float64 ,因為它比 float32 更精確。[開發中,推薦使用 float64]
num6 := 5.12
num7 :=.123
fmt.Println(num6,num7)
//num8:=5.1234e2
//fmt.Println(num8)
num6 := 5.12
num7 :=.123
fmt.Println(num6,num7)
num8:=5.1234e2 //10^2
num9:=5.1234E2 //10^2
num10:=5.1234E-2 //除以10^2
fmt.Println(num8,num9,num10)
4.3 字元型別
1-基本介紹
Golang 中沒有專門的字元型別,如果要儲存單個字元(字母),一般使用 byte 來儲存。
字串就是一串固定長度的字元連線起來的字元序列。Go 的字串是由單個位元組連線起來的。也就是說對於傳統的字串是由字元組成的,而 Go 的字串不同,它是由位元組組成的。
直接輸出byte值,就是輸出了對應的字元的碼值,希望輸出對應的字元,需要使用格式化輸出
var c1 byte ='a'
var c2 byte ='0'
fmt.Println(c1,c2)//97 48
var c1 byte ='a'
var c2 byte ='0'
fmt.Println(c1,c2)
fmt.Printf("c1=%c c2=%c\n",c1,c2)
//var c3 byte = "北"//溢位 21271
var c3 int = '北'
fmt.Printf("c3=%c 對應的碼值=%d",c3,c3)
- 如果我們儲存的字元在 ASCII 表的,比如[0-1, a-z,A-Z..]直接可以儲存到 byte
- 如果我們儲存的字元對應碼值大於 255,這時我們可以考慮使用 int 型別儲存
- 如果我們需要安裝字元的方式輸出,這時我們需要格式化輸出,即 fmt.Printf(“%c”, c1)..
2- 字元型別使用細節
- 字元常量是用單引號(‘’)括起來的單個字元。例如:var c1 byte = ‘a’ var c2 int = ‘中’ var c3 byte = ‘9’
- Go 中允許使用轉義字元 ‘'來將其後的字元轉變為特殊字元型常量。例如:var c3 char = ‘\n’ // ‘\n’表示換行符
- Go 語 言 的 字 符 使 用 UTF-8 編 碼 , 如 果 想 查 詢 字 符 對 應 的 utf8 碼 值www.mytju.com/classcode/tools/encod...
英文字母-1 個位元組 漢字-3 個位元組
- 在 Go 中,字元的本質是一個整數,直接輸出時,是該字元對應的 UTF-8 編碼的碼值。
- 可以直接給某個變數賦一個數字,然後按格式化輸出時%c,會輸出該數字對應的 unicode 字元
- 字元型別是可以進行運算的,相當於一個整數,因為它都對應有 Unicode 碼
n1 =10+ 'a' n1=107
3- 字元型別本質探討
- 字元型 儲存到 計算機中,需要將字元對應的碼值(整數)找出來
儲存:字元—>對應碼值—->二進位制–>儲存
讀取:二進位制—-> 碼值 —-> 字元 –> 讀取
- 字元和碼值的對應關係是通過字元編碼表決定的(是規定好)
- Go 語言的編碼都統一成了 utf-8。非常的方便,很統一,再也沒有編碼亂碼的困擾了
4.4 布林型別
- bool型別,只允許true和false
- bool型別佔1個位元組
- bool型別適於邏輯運算,流程控制
4.5 String型別
Go 語言的字串的位元組使用 UTF-8 編碼標識 Unicode 文字
var address string ="golang"
注意:
- Go 語言的字串的位元組使用 UTF-8 編碼標識 Unicode 文字,這樣 Golang 統一使用 UTF-8 編碼,中文亂碼問題不會再困擾程式設計師。
- 字串一旦賦值了,字串就不能修改了:在 Go 中字串是不可變的
- 字串的兩種表示形式
- 雙引號, 會識別轉義字元
- 反引號,以字串的原生形式輸出,包括換行和特殊字元,可以實現防止攻擊、輸出原始碼等效果
- 字串拼接 【+、+=】
- 一行太長,用字串連線【分行寫】
var str = "hello"
str[0] = 'a'//go中字串不能修改
str1 := "測試\n測試"
str2 := `
func main(){
fmt.Println(123)
}
`
fmt.Println(str1)
fmt.Println(str2)
//
//測試
//測試
// func main(){
// fmt.Println(123)
//}
str3:= "hello" +" go"
str3 += " language"
fmt.Println(str3)
var str string = "張維雙"
fmt.Println(str)
//var str1 string = "hello"
//str1[0] = "a"
str3 := "abc\nabc"
str4 := `abc\nabc`
fmt.Println(str3)
fmt.Println(str4)
str5 := "hello" + "world"
str5 += str5
fmt.Println(str5)
1-基本資料型別的預設值
變數沒有賦值,會有預設值
var a int//0
var b string//""
var c float32//0
var d float64//0
var happy bool//false
var name string//""
fmt.Printf("a=%d,b=%v,c=%v,d=%v,happy=%v,name=%v",a,b,c,d,happy,name)
2-基本資料型別的相互轉換
Go中資料型別只能顯式轉換,不能自動轉換
表示式T(v) 將值v轉換為型別T
T:資料型別,比如int32,int64,float32等
V:需要轉換的變數
var i int32 = 100
var n1 float32 = float32(i)
var n2 float64 = float64(i)
var n3 int8 = int8(i)
var n4 int64 = int64(i)
fmt.Printf("n1=%v,n2=%v,n3=%v,n4=%v",n1,n2,n3,n4)//100
fmt.Printf("%T",i)//int32
fmt.Println(i)//100 //只是把值給了其他變數,但是自身的型別和值沒有變化
var num1 int64 = 999999
var num2 int8 = int8(num1)
fmt.Println(num2)//63
注意:
- 資料型別的轉換可以從小範圍轉為大範圍,也可從大範圍轉小範圍
- 被轉換的是變數儲存的資料(即值),變數本身的資料型別並沒有變化
- 在轉換中,比如將 int64轉成 int8 【-128—127】 ,編譯時不會報錯,只是轉換的結果是按溢位處理,和我們希望的結果不一樣。 因此在轉換時,需要考慮範圍.
- 只有相同型別才能相加,比如
var n1 int32 = 1 |var n2 int64 | varn3=n1+n3
練習
var n1 int32 = 12
var n2 int64
//n2 = n1 + 20 //int32+20 int32!=int64 編譯不通過
n2 = int64(n1) + 20
fmt.Println(n2)
var n1 int32 = 12
var n3 int8
var n4 int8
n4 = int8(n1) + 127 //編譯通過,結果不是127+12 ,按溢位處理
n3 = int8(n1) + 128 //編譯不通過,n3 int8 【-128---127】,直接檢測就報錯了
fmt.Println(n4)
3-基本資料型別和 string 的轉換
我們經常將基本資料型別轉成 string,或者將 string 轉成基本資料型別。
(整型、浮點型、字串、布林)
方式 1:fmt.Sprintf(“%引數”, 表示式) 【個人習慣這個,靈活】
引數需要和表示式的資料型別相匹配
fmt.Sprintf().. 會返回轉換後的字串
//基本資料型別轉string
var num1 int = 99
var num2 float64 = 23.456
var b bool = true
var myChar byte = 'h'
var str string
//第一種方式 fmt.Sprintf方法
str = fmt.Sprintf("%d", num1) //轉的是值
fmt.Printf("str type %T and str=%v\n", str, str) //str type string and str=99
str = fmt.Sprintf("%f", num2)
fmt.Printf("str type %T and str=%v\n", str, str) //str type string and str=23.456000
str = fmt.Sprintf("%t", b)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="true"
str = fmt.Sprintf("%c", myChar)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="h"
方式2:strconv包的函式
func FormatBool(b bool) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
//第二種 strconv
var num3 int = 99
var num4 float64 = 23.456
var b2 bool = true
str := strconv.FormatInt(int64(num3), 10)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="99"
str = strconv.FormatFloat(num4, 'f', 10, 64) //f 展示的格式 ,10:小數點後10位,64:float64
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="23.4560000000"
str = strconv.FormatBool(b2)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="true"
var num5 int = 4567
str = strconv.Itoa(num5)
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="4567"
var num6 int64 = 4567
str = strconv.Itoa(int(num6))
fmt.Printf("str type %T and str=%q\n", str, str) //str type string and str="4567"
4- string 型別轉基本資料型別
func ParseBool(str string) (value bool, err error)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func ParseFloat(s string, bitSize int) (f float64, err error)
func ParseInt
func ParseInt(s string, base int, bitSize int) (i int64, err error)
返回字串表示的整數值,接受正負號。
base指定進位制(2到36),如果base為0,則會從字串前置判斷,"0x"是16進位制,"0"是8進位制,否則是10進位制;
bitSize指定結果必須能無溢位賦值的整數型別,0、8、16、32、64 分別代表 int、int8、int16、int32、int64;返回的err是*NumErr型別的,如果語法有誤,err.Error = ErrSyntax;如果結果超出型別範圍err.Error = ErrRange。
//string轉其他基本型別
var str string = "true"
var b bool
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T and b=%v \n", b, b) //str type string and str="4567"
var str2 string = "1234590"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
fmt.Printf("n1 type %T n1=%v\n", n1, n1)
fmt.Printf("n2 type %T n2=%v\n", n2, n2)
var str3 string = "123.456"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("f1 type %T f1=%v\n", f1, f1)
5- string 型別轉基本資料型別的注意事項
注意,string轉基本資料型別的時候,要考慮到有效性,否則會返回型別 的預設值
"123"轉整型 123
"hello"轉整型 0
var str string = "hello"
var n int64
n, _ = strconv.ParseInt(str, 10, 64)
fmt.Printf("n type %T n=%v\n", n, n)
//n type int64 n=0
var str string = "hello"
var b bool = true
b, _ = strconv.ParseBool(str)
fmt.Printf("b type %T, b=%v\n", b, b)
//b type bool, b=false
1-基本介紹
//基本資料型別在記憶體佈局
var n int = 10
//n 的地址是什麼,&n
fmt.Println("n 的地址=", &n) //n 的地址= 0xc0000a2058
//ptr是一個指標變數
//ptr的型別 *int
//ptr 本身的值&n
var ptr *int = &n
fmt.Printf("ptr=%v\n", ptr) //ptr=0xc0000a2058
fmt.Printf("ptr的地址=%v\n", &ptr) //ptr的地址=0xc000006030
fmt.Printf("ptr指向的值=%v\n", *ptr) //ptr指向的值=10
- 基本資料型別,變數存的就是值,也叫值型別
- 獲取變數的地址,用&,比如 var num int,取地址 &num
- 記憶體佈局如下
指標型別,指標變數存的是這個地址,這個地址指向的空間存的才是值 var ptr *int = &num
- 獲取指標型別所指向的值,使用:* 比如 var ptr int ,使用ptr獲取p指向的值
- 指標在記憶體佈局如下
說白了
指標變數記憶體中存的是地址,這個地址又有真的值
導致指標變數能取地址 &ptr
又能取值 *ptr
2-指標型別的細節
- 值型別,都有對應的指標型別 【資料型別 int–int float–*float】
- 值型別包括:基本資料型別【int\string\boll\float】+陣列+結構體struct
- 引用型別:指標、slice切片、map、管道chan、interface等都是引用型別
3-值型別和引用型別
- 值型別包括:基本資料型別【int\string\boll\float】+陣列+結構體struct
- 引用型別:指標、slice切片、map、管道chan、interface等都是引用型別
4- 值型別和引用型別的使用特點
記憶體中分兩大塊,一塊叫棧區、一塊叫堆區
- 值型別,變數直接儲存值,值型別資料,通常是在棧區上分配
- 引用型別,變數儲存的是一個地址,這個地址對應的空間才真正儲存資料(值),記憶體通常在堆上分配,單沒有任何變數引用這個地址時,該地址對應的資料空間就成為一個垃圾,由GC來回收
1-概念
- Golang 對各種變數、方法、函式等命名時使用的字元序列稱為識別符號
- 凡是自己可以起名字的地方都叫識別符號
2-識別符號的命名規則
- 由26個英文祖瑪大小寫,0-9,_組成
- 數字不可用開頭 var 3num int
- Golang 中嚴格區分大小寫
- 識別符號不能包含空格
- 下劃線,空識別符號,忽略某個值,被佔用,但是可以用_num,【int、float32在這種不推薦】
- 不能以系統保留關鍵字作為識別符號(25個),【break 、if】
3-識別符號的命名規範
- 包名:保持package的名字和目錄一致、不要和標準庫衝突
- 變數名、函式名、常量名使用駝峰法
- 變數名、函式名、常量名首字母大寫能被其他的包訪問
- 變數名、函式名、常量名首字母小寫只能被本包使用
4-系統保留關鍵字
5-系統預定義識別符號
本作品採用《CC 協議》,轉載必須註明作者和本文連結