1. Boolean type
var v1 boolv1 = true;v2 := (1==2) // v2也会被推导为bool类型
2. Integral type
类 型 长度(字节) 值 范 围int8 1 ? 128 ~ 127uint8(即byte)1 0 ~ 255int16 2 ? 32 768 ~ 32 767uint16 2 0 ~ 65 535int32 4 ? 2 147 483 648 ~ 2 147 483 647uint32 4 0 ~ 4 294 967 295int64 8 ? 9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807uint64 8 0 ~ 18 446 744 073 709 551 615int 平台相关 平台相关uint 平台相关 平台相关uintptr 同指针 在32位平台下为4字节,64位平台下为8字节var value2 int32value1 := 64 // value1将会被自己主动推导为int类型value2 =value1 //编译失败:cannot use value1 (type int) as type int32 in assignment。
//使用强制类型转换可解决value2 = int32(value1)
3. Numerical operations
常规运算:+、-、*、/和%比較运算: > 、 < 、 == 、 >= 、 <= 和 !=须要注意:两个不同类型的整型数不能直接比較,比方 int8 类型的数和 int类型的数不能直接比較,但各种类型的整型变量都能够直接与字面常量(literal)进行比較,比方:
varint32varint64i, j = 1, 2if// 编译错误fmt.Println("i and j are equal.")}if i == 1 || j == 2// 编译通过fmt.Println("i and j are equal.")}
4. Bit arithmetic
x << y 左移 x >> y 右移 x ^ y 异或 x & y 与 x | y 或 ^x 取反
5. Floating-point types
Go语言定义了两个类型 float32 和 float64 ,当中 float32 等价于C语言的 float 类型,float64 等价于C语言的 double 类型。var fvalue1 float32fvalue1 = 12fvalue2 := 12.0 // 假设不加小数点,fvalue2会被推导为整型而不是浮点型对于以上样例中类型被自己主动推导的 fvalue2 。须要注意的是其类型将被自己主动设为 float64 ,而无论赋给它的数字是否是用32位长度表示的。因此,对于以上的样例。以下的赋值将导致编译错误:fvalue1 = fvalue2而必须使用这种强制类型转换:fvalue1 = float32(fvalue2)
5.1 Floating point comparison
由于浮点数不是一种精确的表达方式,所以像整型那样直接用 == 来推断两个浮点数是否相等是不可行的。这可能会导致不稳定的结果。以下是一种推荐的替代方案:
import"math"// p为用户自己定义的比較精度,比方0.00001funcfloat64bool { return math.Fdim(f1, f2) < p}
6. plural
复数实际上由两个实数(在计算机中用浮点数表示)构成,一个表示实部(real),一个表示虚部(imag)。假设了解了数学上的复数是怎么回事,那么Go语言的复数就很easy理解了。
6.1 Plural representation
var value1 complex64 // 由2个float32构成的复数类型value1 = 3.2 + 12ivalue2 := 3.2 + 12i // value2是complex128类型value3 := complex(3.2, 12) // value3结果同 value2
6.2 Real part and imaginary part
对于一个复数 z = complex(x, y) ,就能够通过Go语言内置函数 real(z) 获得该复数的实部,也就是 x ,通过 imag(z) 获得该复数的虚部,也就是 y 。
7. String
Go语言中字符串的声明和初始化很简单。举比例如以下:
varstring // 声明一个字符串变量"Hello world"// 字符串赋值ch := str[0// 取字符串的第一个字符fmt.Printf("The length of \"%s\" is %d \n"len(str))fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)
输出结果为:The length of "Hello world" is 11The first character of "Hello world" is H.
字符串的内容能够用相似于数组下标的方式获取,但与数组不同,字符串的内容不能在初始化后被改动,比方以下的样例:str := "Hello world" // 字符串也支持声明时进行初始化的做法str[0] = ‘X‘ // 编译错误编译器会报相似例如以下的错误:cannot assign to str[0]假设想改动字符串的内容,能够通过例如以下的方式改动:
"hello"c := []rune//将字符串s转成rune数组c[0‘x‘//改动rune数组中的第一个元素为xstring//根据rune数组创建一个新的字符串fmt.Println("s2=",s2)
执行结果: s2= xello
7.1 String Manipulation
x + y 字符串连接 "Hello" + "123" // 结果为Hello123len(s) 字符串长度 len("Hello") // 结果为5s[i] 取字符 "Hello" [1] // 结果为‘e‘
7.2 Multi-line string
使用多行字符串须要小心,比如:s := "Hello " +"world"编译时会被自己主动转换成:s := "Hello "; +"world";此时会编译失败,报错:invalid operation: + untyped string 正确的多行写法是这种:s := "Hello " + "world"Go 就不会在错误的地方插入分号。
还有一种写法是使用反引號 ` 作为原始字符串符号:s := `Hello world`
7.3 String Traversal
Go语言支持两种方式遍历字符串。
一种是以字节数组的方式遍历:
"abc中国"len(str)for i := 0; i < n; i++ { // 根据下标取字符串中的字符,类型为byte fmt.Printf("i=%v\n", ch)}
输出结果:i=97 //ai=98 //bi=99 //ci=228 //中字的第一字节,每一个中文字符在UTF-8中占3个字节i=184 //中字的第二个字节i=173 //中字的第三个字节i=229 //国字的第一个字节i=155 //国字的第二个字节i=189 //国字的第三个字节
还有一种是以Unicode字符遍历,以Unicode字符方式遍历时,每一个字符的类型是 rune (早期的Go语言用 int 类型表示Unicode字符),而不是byte.
"abc中国"forrange str{ //range关键字在数组中有介绍 fmt.Println(i,ch) //ch的类型为rune}
//输出结果:0 971 982 993 20013 6 22269
8. Character types
在Go语言中支持两个字符类型,一个是 byte (实际上是 uint8 的别名),代表UTF-8字符串的单个字节的值;还有一个是 rune 。代表单个Unicode字符。出于简化语言的考虑,Go语言的多数API都假设字符串为UTF-8编码。虽然Unicode字符在标准库中有支持。但实际上较少使用。
9. Arrays
以下为一些常规的数组声明方法:[32]byte // 长度为32的数组,每一个元素为一个字节[2*N] struct { x, y int32 } // 复杂类型数组[1000]*float64 // 指针数组[3][5]int // 二维数组[2][2][2]float64 // 等同于[2]([2]([2]float64))在Go语言中。数组长度在定义后就不可更改,在声明时长度能够为一个常量或者一个常量表达式(常量表达式是指在编译期就可以计算结果的表达式)。
9.1 Elements of the interview
能够使用数组下标来訪问数组中的元素。与C语言同样,数组下标从0到len(array)-1,以下的演示样例遍历整型数组并逐个打印元素内容:
//通过for循环遍历for i := 0len(array); i++ { fmt.Println("Element""of array is", array[i])}//Go语言还提供了一个关键字range,用于便捷地遍历容器中的元素。//当然,数组也是range的支持范围。上面的遍历过程能够简化为例如以下的写法:forrange array { //k相当于索引,v相当于值 fmt.Println("Array element[""]=", v) }
9.2 Value Operation
The requires special attention. In the go language, an array is a value type (value).
All value-type variables produce a copy action when they are assigned and passed as a parameter. The
assumes that the array is the parameter type of the function, and that the parameter will occur when the function is called for data replication.
Therefore, the contents of the incoming array cannot be altered in the body of the function, because only one copy of the incoming array is manipulated within the function. The following example illustrates this feature:
func main(){ [5]int{1,2,3,4,5} modify(array) fmt.Println("In main(),array values:",array)}func[5int){ array[0] = 10 fmt.Println("In modify(),array values:",array)}
//输出结果:In modify(), array values: [10 2 3 4 5]In main(), array values: [1 2 3 4 5]
从执行结果能够看出,函数 modify() 内操作的那个数组跟 main() 中传入的数组是两个不同的实例。那么。怎样才干在函数内操作外部的数据结构呢?这个就要用到后接下来要讲的数组切片.
10. Array slicing
在前一节里我们已经提过数组的特点:数组的长度在定义之后无法再次改动;数组是值类型。每次传递都将产生一份副本。显然这种数据结构无法全然满足开发人员的真实需求。
Go语言提供了数组切片(slice)这个很酷的功能来弥补数组的不足,能够随时动态扩充存放空间,而且能够被任意传递而不会导致所管理的元素被反复复制。有点相似于java中的集合.数组切片的数据结构能够抽象为以下3个变量:一个指向原生数组的指针;数组切片中的元素个数;数组切片已分配的存储空间。
10.1 Creating an Array slice
(1)基于已存在数组创建,数组切片能够仅仅使用数组的一部分元素或者整个数组来创建。甚至能够创建一个比所基于的数组还要大的数组切片。
varMyArray[Ten]int=[Ten]int{1, 2, 3, 4, 5, 6, 7, 8, 9, ten}//Create an array slice based on the first 5 elements of the arrayvarMyslice []int= myarray[: 5]fmt. Println ("Elements of MyArray:") for_, V: =Rangemyarray{FMT. Print (V," ")}fmt. Println ("\nelements of Myslice:") for_, v:=Rangemyslice{FMT. Print (V," ")}
//输出结果:Elements of myArray:1 2 3 4 5 6 7 8 9 10Elements of mySlice:1 2 3 4 5
Go语言支持用 myArray[first:last] 这种方式来基于数组生成一个数组切片,而且这个使用方法还很灵活,比方以下几种都是合法的。a.基于 myArray 的全部元素创建数组切片:mySlice = myArray[:]b.基于 myArray 的前5个元素创建数组切片:mySlice = myArray[:5]c.基于从第5个元素開始的全部元素创建数组切片:mySlice = myArray[5:](2)通过make()函数直接创建数组切片创建一个初始元素个数为5的数组切片,元素初始值为0:mySlice1 := make([]int,5)创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:mySlice2 := make([]int,5,10) 通过cap()函数能够获取切片的分配空间,len()函数能够知道当前已存储的元素个数.
fmt.Println("len(mySlice2):"len(mySlice2))fmt.Println("cap(mySlice2):"cap(mySlice2))
//输出结果:len(mySlice2): 5cap(mySlice2): 10
当然,其实还会有一个匿名数组被创建出来。仅仅是不须要我们来担心而已。(3)直接在声明的时候并初始化mySlice3 := []int{8,9,10}(4)基于数组切片创建数组切片oldSlice := []int{1,2,3,4,5}newSlice := oldSlice[:3] //基于oldSlice的前3个元素创建
10.2 element traversal of array slices
操作数组的全部方法都适合数组切片,通过上面的代码也能够看得出来共同拥有2种方式:for循环遍历,或者for循环结合range来操作
10.3 Dynamic increment and decrement of array slice elements
与数组相比,数组切片多了一个存储能力的概念,即元素个数和分配的空间能够是两个不同的值,合理地设置存储能力的值,能够大幅减少数组切片内部又一次分配内存和搬送内存块的频率,从而大大提高程序性能。
通过append()函数能够在切片后面追加元素,比如:mySlice = append(mySlice, 8, 9, 10) append()函数的第二个參数是个不定的參数,有点相似java中的可变參数,甚至能够追加1个数组切片mySlice2 := []int{8,9,10}mySlice = append(mySlice,mySlice2...) //注意:这3个...点不能省略,否则编译失败
10.4 Content Replication
通过copy()函数,能够将一个数组切片拷贝到还有一个数组切片中,假设2个的数组切片不一样大,则会按当中较小的那个数组切片的元素个数进行复制.slice1 := []int{1,2,3,4,5}slice2 := []int{5,4,3}copy(slice2,slice1) //仅仅会复制slice1的前3个元素到slice2中,slice2中的值被自己主动替换copy(slice1,slice2) //仅仅会复制slice2的3个元素到slice1的前3个位置,该3个位置的值自己主动替换,其它的不变
11.map
在C++/Java中。map一般都以库(导包)的方式提供,在C++/Java中, 而在Go中,使用map 不须要引入不论什么库。而且用起来也更加方便。看以下的样例:
typePersonInfostruct{IDstringNamestringAddressstring}funcMain () {varPersondbMap[string] PersonInfo//Declaration of a Key=string,value=personinfo mapPERSONDB = Make(Map[string] PersonInfo)//Initialize with make //Insert a few data into this mappersondb["0"] = personinfo{"12345","Tom","203,..."} persondb["1"] = personinfo{"1","Jack","101,..."}//.... //Find the information for key 12345 from this mapperson, OK: = persondb["0"]//If found, then ok=true, otherwise =false ifok{FMT. Println ("Found person", person. Name,"with ID", Person.id)}Else{FMT. Println ("did not find the person") }}
//执行结果:Found person Tom with ID 12345
Statement of the 11.1map
Creation of 11.2map
(1)通过make()函数创建
var myMap map [int ] string MyMap = make (map [ int ] string ) //can also be written as a statement: MyMap: = Make (map[int]string) mymap[0 ] = "1" //assignment MyMap [1 ] = "2" result,_: = MyMap [0 ] //this uses the anonymous variable fmt. Println ( "mymap[0]=" , result) fmt. Println ( "mymap[1]=" , Mymap[1 ])
//执行结果:myMap[0]= 1myMap[1]= 2
通过make创建的时候,还能够指定其初始容量myMap2 := make(map[int]string,100)(2)方式2,通过{}赋值的方式创建
map[int]string{ 0:"张三", 1:"李四",}fmt.Println("myMap3[0]=",myMap3[0])fmt.Println("myMap3[1]=",myMap3[1])
//执行结果:myMap3[0]= 张三myMap3[1]= 李四
11.3 Deletion of elements
通过delete()函数完毕,形如:delete(map变量名,map的key)假设要删除的元素没有相应的key,则什么都不发生,可是假设传入的map变量的值是 nil 。该调用将导致程序抛出异常(panic)。
11.4 Searching for elements
map通过key查找,能够返回2个变量,第一个为相应key的值,第二个为是否查找成功的bool,形如:
map[key]if ok{ //找到了,处理value}else{ //未找到}
当然,假设你很确定该key一定能够找到相应的值的话,那就能够直接使用一个变量来接收,比如:value := map[key]或者,第二个參数用匿名參数来接收,比如:value,_ := map[key]
11.5 Traversal of elements
(1)使用for循环遍历
make(map[int]int)myMap[0] = 100myMap[1] = 101myMap[2] = 102for i:=0;i<len(myMap);i++ { fmt.Println("key=",i," value=",myMap[i])}
执行结果:key= 0 value= 100key= 1 value= 101key= 2 value= 102
(2)使用for循环结合range关键字遍历
map[int]int{ 0 : 10, 1 : 20, 2 : 30,}forrange myMap{ fmt.Println("key=",k," value=",v)}
执行结果:key= 0 value= 10key= 1 value= 20key= 2 value= 30
Go language Learning (iv) frequently used types Introduction