基礎型別有哪些?布林型(bool)數值型有符號整數:int8, int16, int32, int64, int無符號整數:uint8, uint16, uint32, uint64, uint浮點型:float32, float64複合型:complex64, complex128位元組型:byterune字串(string)布林型別(bool)
布林型別表示布林值,可以為true或false。
package mainimport "fmt"func main() { a := true b := false fmt.Println("a:", a, "b:", b) c := a && b fmt.Println("c:", c) d := a || b fmt.Println("d:", d)}
執行結果:
a: true b: false c: false d: true
有符號整數int8: 表示8位有符號整數大小: 8位範圍: -128至127int16: 表示16位有符號整數大小: 16位範圍: -32768至32767int32:表示32位有符號整數大小: 32位範圍: -2147483648至2147483647int64: 表示64位有符號整數大小: 64位範圍: -9223372036854775808至9223372036854775807int: 表示32或64位整數,具體取決於基礎平臺。大小:在32位作業系統中為32位,在64位作業系統中為64位。範圍:在32位系統中為-2147483648至2147483647,在64位系統中為-9223372036854775808至9223372036854775807在go中我們可以使用Printf函式%T格式來列印變數的型別,如果要獲取變數的大小,則使用unsafe包中的Sizeof函式(返回的是位元組數)來獲取。例如:
package mainimport ( "fmt" "unsafe")func main() { var num1 int = 10 num2 := 20 fmt.Println("num1 = ", num1, "num2:", num2) fmt.Printf("num1的型別: %T, num1的大小: %d", num1, unsafe.Sizeof(num1)) fmt.Println() fmt.Printf("num2的型別: %T, num2的大小: %d", num2, unsafe.Sizeof(num2))}
執行結果:
num1 = 10 num2: 20num1的型別: int, num1的大小: 8num2的型別: int, num2的大小: 8
為什麼int型別的變數大小是8呢? 這是因為int型別的大小與作業系統的位數有關,這裡是8個位元組,這就代表執行go程式的作業系統是64位的。
無符號整數uint8: 表示8位無符號整數大小: 8位範圍: 0至255uint16:表示16位無符號整數大小: 16位範圍: 0到65535uint32: 表示32位無符號整數大小: 32位範圍: 0至4294967295uint64: 表示64位無符號整數大小: 64位範圍: 0至18446744073709551615uint: 表示32或64位無符號整數,具體取決於基礎平臺。大小: 32位系統中為32位,64位系統中為64位。 範圍:在32位系統中為0到4294967295,在64位系統中為0到18446744073709551615
關於有符號整數與無符號整數的解釋下面我們將以int8 與 uint8為例進行解釋
var ( num1 uint8 = 255 num2 int8 = -128)
以上我們定義了兩個變數num1(無符號)和num2(有符號),對於num1我們能很快知道它的二進位制數:11111111,而num2所對應的二進位制數又是什麼呢?
在二進位制中表示負數時,一般會把最高位作為符號位來使用。符號位是0表示正數,符號位是1表示負數。
那-128的二進位制數是多少呢?答案是:10000000。這個數是怎麼得來的呢?在計算機中,二進位制的儲存都是有的補碼,正數的原碼、反碼和補碼相同,負數的原碼是最高位為1,反碼最高位不變,其餘各位取反,補碼為其反碼+1。
10000000 //128原始值01111111 //取反 反碼10000000 //加1,即獲得補碼
浮點型別float32: 32位浮點數float64: 64位浮點數
示例:
package mainimport "fmt"func main() { num1, num2 := 5.67, 8.97 fmt.Printf("num1型別:%T num2型別:%T", num1, num2) fmt.Println() sum := num1 + num2 diff := num1 - num2 fmt.Println("sum:", sum, "diff:", diff)}
執行結果:
num1型別:float64 num2型別:float64sum: 14.64 diff: -3.3000000000000007
複合型別
complex64:具有float32實部和虛部的複數 complex128:具有float64實部和虛部的複數
想要構建實部和虛部的複數是透過內建函式complex完成的。
package mainimport ( "fmt")func main() { complexNumber1 := complex(3, 4) complexNumber2 := 5 + 6i sum := complexNumber1 + complexNumber2 fmt.Println("和:", sum) reduce := complexNumber1 + complexNumber2 fmt.Println("差:", reduce) product := complexNumber1 * complexNumber1 fmt.Println("積:", product) divide := complexNumber1 / complexNumber1 fmt.Println("除:", divide)}
執行結果:
和: (8+10i)差: (8+10i)積: (-7+24i)除: (1+0i)
關於複數運演算法則: 假設c1=a+bi,c2=c+di是任意兩個複數
加法法則:(a+bi)+(c+di)=(a+c)+(b+d)i減法法則:(a+bi)-(c+di)=(a-c)+(b-d)i。乘法法則:(a+bi)(c+di)=(ac-bd)+(bc+ad)i除法法則:滿足(c+di)(x+yi)=(a+bi)的複數x+yi(x,y∈R)叫複數a+bi除以複數c+di的商其他數值型別byte: 是uint8的別名,代表了ASCII碼的一個字元rune: 是int32的別名, 代表一個UTF-8 字元,當需要處理中文、日文或者其他複合字符時,則需要用到rune型別。示例:
package mainimport ( "fmt")func main() { a := 'a' A := 65 var str string = "中國" fmt.Printf("a的ascii碼是:%d", int8(a)) fmt.Println() fmt.Printf("A所對應字元是:%c", A) fmt.Println() fmt.Println("str所對應Unicode碼是:", []rune(str))}
執行結果:
a的ascii碼是:97A所對應字元是:Astr所對應Unicode碼是: [20013 22269]
ASCII碼、Unicode碼、UTF-8是什麼?ASCII碼: 一種字符集,使用7 位二進位制數(剩下的1位二進位制為0)來表示所有的大寫和小寫字母,數字0 到9、標點符號,以及在美式英語中使用的特殊控制字元。例如:小寫a的ASCII是:97,大寫A的是:65Unicode碼: 也是一種字元編碼,它為每種語言中的每個字元設定了統一併且唯一的二進位制編碼,以滿足跨語言、跨平臺進行文字轉換、處理的要求。例如:“中國” 在Unicode的編碼是:20013和22269。UTF-8: 一種編碼規則,對Unicode的一種可變長度字元編碼。使用1~4位元組為每個字元進行編碼。一個ASCIl字元只需要一個位元組編碼,其他語言的字元(包括中日韓文字、東南亞文字、中東文字等)包含了大部分常用字,使用3位元組編碼。字串型別
在go中,字串是位元組的集合。
package mainimport ( "fmt")func main() { var str string = "go基礎程式設計(三)" strRune := []rune(str) fmt.Println("str長度:", len(str), " 第一個字元Unicode編碼:", str[0]) fmt.Println("strRune長度和strRune第一個字元Unicode編碼", len(strRune), strRune[0]) fmt.Println("str第一個和三個字元所對應的Unicode編碼:", strRune[0], strRune[2]) fmt.Printf("str第一個和第三個字元: %c, %s", str[0], string(strRune[2])) fmt.Println() fmt.Printf("str第一個和第三個字元型別: %T , %T", strRune[0], strRune[2])}
執行結果:
str長度: 23 第一個字元Unicode編碼: 103strRune長度和strRune第一個字元Unicode編碼 9 103str第一個和三個字元所對應的Unicode編碼: 103 22522str第一個和第三個字元: g, 基str第一個和第三個字元型別: int32 , int32
型別轉換
在go中不存在隱式型別轉換,所有的型別轉換都必須顯式的宣告。格式:
valueOfTypeB = typeB(valueOfTypeA)
示例:
package mainimport "fmt"func main() { f := 3.14 b := 5 sum := int(f) + b fmt.Println("sum: ", sum)}
執行結果:
f的型別:float64sum: 8
上面程式碼:int(f) 就是將float64轉換成int型別。
型別斷言型別斷言的作用主要是判斷一個變數的型別是什麼,其型別斷言表示式:
value, ok := interface{}.(type)
value: 是布林(bool)型別的,它將代表型別判斷的結果,true或falseok : 如果是true,那麼被判斷的值將會被自動轉換為[]string型別的值,並賦給變數value,否則value將被賦予type型別的零值。示例:
package mainimport "fmt"func main() { // 定義一個interface{}型別變數,並使用float型別值”abc“初始化 var str interface{} = "go 基礎程式設計(三)" value, ok := str.(int) fmt.Println(value, ok) fmt.Println("-------------------") switch str.(type) { case int: fmt.Println("我是int 型別") case rune: fmt.Println("我是rune型別") case string: fmt.Println("我是字串型別") default: fmt.Println("沒有匹配上") }}
執行結果:
0 false-------------------我是字串型別
注意:如果使用 .(type) 查詢型別的變數不是 interface{} 型別,在編譯時就會報錯。
示例:
a := 123a.(string)
執行結果:
invalid type assertion: a.(string) (non-interface type int on left)
.(type)只能在switch中使用,否則會報錯:var b interface{} = 456fmt.Println(b.(type))
執行結果:
use of .(type) outside type switch
.(type)在switch中,要查詢型別的變數不是 interface{} 型別,則在編譯時會報如下錯誤:
str := "go 基礎程式設計(三)"switch str.(type) {case int: fmt.Println("我是int 型別")case rune: fmt.Println("我是rune型別")case string: fmt.Println("我是字串型別")default: fmt.Println("沒有匹配上")}
執行結果: