1.布尔类型

  1. var v1 bool
  2. v1 = true;
  3. v2 := (1==2) // v2也会被推导为bool类型

2.整型

  1. 长度(字节)
  2. int8 1 128 ~ 127
  3. uint8(即byte1 0 ~ 255
  4. int16 2 32 768 ~ 32 767
  5. uint16 2 0 ~ 65 535
  6. int32 4 2 147 483 648 ~ 2 147 483 647
  7. uint32 4 0 ~ 4 294 967 295
  8. int64 8 9 223 372 036 854 775 808 ~ 9 223 372 036 854 775 807
  9. uint64 8 0 ~ 18 446 744 073 709 551 615
  10. int 平台相关 平台相关
  11. uint 平台相关 平台相关
  12. uintptr 同指针 32位平台下为4字节,64位平台下为8字节
  13. var value2 int32
  14. value1 := 64 // value1将会被自己主动推导为int类型
  15. value2 =value1 //编译失败:cannot use value1 (type int) as type int32 in assignment。
  16. //使用强制类型转换可解决
  17. value2 = int32(value1)

3.数值运算

  1. 常规运算:+、-、*、/和%
  2. 比較运算: > < == >= <= !=
  3. 须要注意:两个不同类型的整型数不能直接比較,比方 int8 类型的数和 int类型的数不能直接比較,但各种
  4. 类型的整型变量都能够直接与字面常量(literal)进行比較,比方:
  1. var i int32
  2. var j int64
  3. i, j = 1, 2
  4. if i == j { // 编译错误
  5. fmt.Println("i and j are equal.")
  6. }
  7. if i == 1 || j == 2 { // 编译通过
  8. fmt.Println("i and j are equal.")
  9. }

4.位运算

  1. x << y 左移
  2. x >> y 右移
  3. x ^ y 异或
  4. x & y
  5. x | y
  6. ^x 取反

5.浮点类型

  1. Go语言定义了两个类型 float32 float64 ,当中 float32 等价于C语言的 float 类型,
  2. float64 等价于C语言的 double 类型。
  3. var fvalue1 float32
  4. fvalue1 = 12
  5. fvalue2 := 12.0 // 假设不加小数点,fvalue2会被推导为整型而不是浮点型
  6. 对于以上样例中类型被自己主动推导的 fvalue2 。须要注意的是其类型将被自己主动设为 float64
  7. 而无论赋给它的数字是否是用32位长度表示的。因此,对于以上的样例。以下的赋值将导致编译
  8. 错误:
  9. fvalue1 = fvalue2
  10. 而必须使用这种强制类型转换:
  11. fvalue1 = float32(fvalue2)

5.1浮点数比較

  1. 由于浮点数不是一种精确的表达方式,所以像整型那样直接用 == 来推断两个浮点数是否相等
  2. 是不可行的。这可能会导致不稳定的结果。
  3. 以下是一种推荐的替代方案:
  1. import "math"
  2. // p为用户自己定义的比較精度,比方0.00001
  3. func IsEqual(f1, f2, p float64) bool {
  4. return math.Fdim(f1, f2) < p
  5. }

6.复数

  1. 复数实际上由两个实数(在计算机中用浮点数表示)构成,一个表示实部(real),一个表示
  2. 虚部(imag)。假设了解了数学上的复数是怎么回事,那么Go语言的复数就很easy理解了。

6.1复数表示

  1. var value1 complex64 // 由2个float32构成的复数类型
  2. value1 = 3.2 + 12i
  3. value2 := 3.2 + 12i // value2是complex128类型
  4. value3 := complex(3.2, 12) // value3结果同 value2

6.2 实部与虚部

  1. 对于一个复数 z = complex(x, y) ,就能够通过Go语言内置函数 real(z) 获得该复数的实
  2. 部,也就是 x ,通过 imag(z) 获得该复数的虚部,也就是 y

7.字符串

  1. Go语言中字符串的声明和初始化很简单。举比例如以下:
  1. var str string // 声明一个字符串变量
  2. str = "Hello world" // 字符串赋值
  3. ch := str[0] // 取字符串的第一个字符
  4. fmt.Printf("The length of \"%s\" is %d \n", str, len(str))
  5. fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)
  1. 输出结果为:
  2. The length of "Hello world" is 11
  3. The first character of "Hello world" is H.

  1. 字符串的内容能够用相似于数组下标的方式获取,但与数组不同,字符串的内容不能在初始
  2. 化后被改动,比方以下的样例:
  3. str := "Hello world" // 字符串也支持声明时进行初始化的做法
  4. str[0] = 'X' // 编译错误
  5. 编译器会报相似例如以下的错误:
  6. cannot assign to str[0]
  7. 假设想改动字符串的内容,能够通过例如以下的方式改动:
  1. s := "hello"
  2. c := []rune(s) //将字符串s转成rune数组
  3. c[0] = 'x' //改动rune数组中的第一个元素为x
  4. s2 := string(c) //根据rune数组创建一个新的字符串
  5. fmt.Println("s2=",s2)
  1. 执行结果:
  2. s2= xello

7.1字符串操作

  1. x + y 字符串连接 "Hello" + "123" // 结果为Hello123
  2. len(s) 字符串长度 len("Hello") // 结果为5
  3. s[i] 取字符 "Hello" [1] // 结果为'e'

7.2多行字符串

  1. 使用多行字符串须要小心,比如:
  2. s := "Hello "
  3. +"world"
  4. 编译时会被自己主动转换成:
  5. s := "Hello ";
  6. +"world";
  7. 此时会编译失败,报错:invalid operation: + untyped string
  8. 正确的多行写法是这种:
  9. s := "Hello " +
  10. "world"
  11. Go 就不会在错误的地方插入分号。
  12. 还有一种写法是使用反引號 ` 作为原始字符串符号:
  13. s := `Hello
  14. world`

7.3字符串遍历

  1. Go语言支持两种方式遍历字符串。
  2. 一种是以字节数组的方式遍历:
  1. str := "abc中国"
  2. n := len(str)
  3. for i := 0; i < n; i++ {
  4. ch := str[i] // 根据下标取字符串中的字符,类型为byte
  5. fmt.Printf("i=%v\n", ch)
  6. }
  1. 输出结果:
  2. i=97 //a
  3. i=98 //b
  4. i=99 //c
  5. i=228 //中字的第一字节,每一个中文字符在UTF-8中占3个字节
  6. i=184 //中字的第二个字节
  7. i=173 //中字的第三个字节
  8. i=229 //国字的第一个字节
  9. i=155 //国字的第二个字节
  10. i=189 //国字的第三个字节

  1. 还有一种是以Unicode字符遍历,以Unicode字符方式遍历时,每一个字符的类型是 rune
  2. (早期的Go语言用 int 类型表示Unicode字符),而不是byte.
  1. str := "abc中国"
  2. for i, ch := range str{ //range关键字在数组中有介绍
  3. fmt.Println(i,ch) //ch的类型为rune
  4. }
  1. //输出结果:
  2. 0 97
  3. 1 98
  4. 2 99
  5. 3 20013
  6. 6 22269

8.字符类型

  1. Go语言中支持两个字符类型,一个是 byte (实际上是 uint8 的别名),代表UTF-8字符串的单个字节的值;
  2. 还有一个是 rune 。代表单个Unicode字符。出于简化语言的考虑,Go语言的多数API都假设字符串为UTF-8编码。
  3. 虽然Unicode字符在标准库中有支持。但实际上较少使用。

9.数组

  1. 以下为一些常规的数组声明方法:
  2. [32]byte // 长度为32的数组,每一个元素为一个字节
  3. [2*N] struct { x, y int32 } // 复杂类型数组
  4. [1000]*float64 // 指针数组
  5. [3][5]int // 二维数组
  6. [2][2][2]float64 // 等同于[2]([2]([2]float64))
  7. Go语言中。数组长度在定义后就不可更改,在声明时长度能够为一个常量或
  8. 者一个常量表达式(常量表达式是指在编译期就可以计算结果的表达式)。

9.1元素的訪问

  1. 能够使用数组下标来訪问数组中的元素。与C语言同样,数组下标从0len(array)-1,
  2. 以下的演示样例遍历整型数组并逐个打印元素内容:
  1. //通过for循环遍历
  2. for i := 0; i < len(array); i++ {
  3. fmt.Println("Element", i, "of array is", array[i])
  4. }
  5. //Go语言还提供了一个关键字range,用于便捷地遍历容器中的元素。
  6. //当然,数组也是range的支持范围。上面的遍历过程能够简化为例如以下的写法:
  7. for k, v := range array { //k相当于索引,v相当于值
  8. fmt.Println("Array element[", k, "]=", v)
  9. }

9.2值操作

  1. 须要特别注意的是。在Go语言中数组是一个值类型(value type)。
  2. 全部的值类型变量在赋值
  3. 和作为參数传递时都将产生一次复制动作。
  4. 假设将数组作为函数的參数类型,则在函数调用时该
  5. 參数将发生数据复制。
  6. 因此,在函数体中无法改动传入的数组的内容,由于函数内操作的仅仅是所
  7. 传入数组的一个副本。以下用样例来说明这一特点:
  1. func main(){
  2. array := [5]int{1,2,3,4,5}
  3. modify(array)
  4. fmt.Println("In main(),array values:",array)
  5. }
  6. func modify(array [5] int){
  7. array[0] = 10
  8. fmt.Println("In modify(),array values:",array)
  9. }
  1. //输出结果:
  2. In modify(), array values: [10 2 3 4 5]
  3. In main(), array values: [1 2 3 4 5]

  1. 从执行结果能够看出,函数 modify() 内操作的那个数组跟 main() 中传入的数组是两个不同的实
  2. 例。那么。怎样才干在函数内操作外部的数据结构呢?这个就要用到后接下来要讲的数组切片.

10.数组切片

  1. 在前一节里我们已经提过数组的特点:数组的长度在定义之后无法再次改动;数组是值类型。
  2. 每次传递都将产生一份副本。显然这种数据结构无法全然满足开发人员的真实需求。
  3. Go语言提供了数组切片(slice)这个很酷的功能来弥补数组的不足,能够随时动态扩充存放空
  4. 间,而且能够被任意传递而不会导致所管理的元素被反复复制。有点相似于java中的集合.
  5. 数组切片的数据结构能够抽象为以下3个变量:
  6. 一个指向原生数组的指针;
  7. 数组切片中的元素个数;
  8. 数组切片已分配的存储空间。

10.1创建数组切片

  1. (1)基于已存在数组创建,数组切片能够仅仅使用数组的一部分元素或者整个数组来创建。
  2. 甚至能够创建一个比所基于的数组还要大的数组切片。
  1. var myArray [10]int = [10]int{1,2,3,4,5,6,7,8,9,10}
  2. // 基于数组前5个元素创建一个数组切片
  3. var mySlice []int = myArray[:5]
  4. fmt.Println("Elements of myArray:")
  5. for _, v := range myArray{
  6. fmt.Print(v," ")
  7. }
  8. fmt.Println("\nElements of mySlice:")
  9. for _, v:= range mySlice{
  10. fmt.Print(v," ")
  11. }
  1. //输出结果:
  2. Elements of myArray:
  3. 1 2 3 4 5 6 7 8 9 10
  4. Elements of mySlice:
  5. 1 2 3 4 5

  1. Go语言支持用 myArray[first:last] 这种方式来基于数组生成一
  2. 个数组切片,而且这个使用方法还很灵活,比方以下几种都是合法的。
  3. a.基于 myArray 的全部元素创建数组切片:
  4. mySlice = myArray[:]
  5. b.基于 myArray 的前5个元素创建数组切片:
  6. mySlice = myArray[:5]
  7. c.基于从第5个元素開始的全部元素创建数组切片:
  8. mySlice = myArray[5:]
  9. (2)通过make()函数直接创建数组切片
  10. 创建一个初始元素个数为5的数组切片,元素初始值为0:
  11. mySlice1 := make([]int,5)
  12. 创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
  13. mySlice2 := make([]int,5,10)
  14. 通过cap()函数能够获取切片的分配空间,len()函数能够知道当前已存储的元素个数.
  1. fmt.Println("len(mySlice2):", len(mySlice2))
  2. fmt.Println("cap(mySlice2):", cap(mySlice2))
  1. //输出结果:
  2. len(mySlice2): 5
  3. cap(mySlice2): 10

  1. 当然,其实还会有一个匿名数组被创建出来。仅仅是不须要我们来担心而已。
  2. (3)直接在声明的时候并初始化
  3. mySlice3 := []int{8,9,10}
  4. (4)基于数组切片创建数组切片
  5. oldSlice := []int{1,2,3,4,5}
  6. newSlice := oldSlice[:3] //基于oldSlice的前3个元素创建

10.2数组切片的元素遍历

  1. 操作数组的全部方法都适合数组切片,通过上面的代码也能够看得出来共同拥有2种方式:
  2. for循环遍历,或者for循环结合range来操作

10.3数组切片元素的动态增减

  1. 与数组相比,数组切片多了一个存储能力的概念,即元素个数和分配的空间能够是两个不同的值,
  2. 合理地设置存储能力的值,能够大幅减少数组切片内部又一次分配内存和搬送内存块的频率,
  3. 从而大大提高程序性能。
  4. 通过append()函数能够在切片后面追加元素,比如:
  5. mySlice = append(mySlice, 8, 9, 10)
  6. append()函数的第二个參数是个不定的參数,有点相似java中的可变參数,甚至能够追加1个数组切片
  7. mySlice2 := []int{8,9,10}
  8. mySlice = append(mySlice,mySlice2...) //注意:这3个...点不能省略,否则编译失败

10.4内容复制

  1. 通过copy()函数,能够将一个数组切片拷贝到还有一个数组切片中,
  2. 假设2个的数组切片不一样大,则会按当中较小的那个数组切片的元素个数进行复制.
  3. slice1 := []int{1,2,3,4,5}
  4. slice2 := []int{5,4,3}
  5. copy(slice2,slice1) //仅仅会复制slice1的前3个元素到slice2中,slice2中的值被自己主动替换
  6. copy(slice1,slice2) //仅仅会复制slice2的3个元素到slice1的前3个位置,该3个位置的值自己主动替换,其它的不变

11.map

  1. C++/Java中。map一般都以库(导包)的方式提供,在C++/Java中,
  2. 而在Go中,使用map 不须要引入不论什么库。而且用起来也更加方便。看以下的样例:
  1. type PersonInfo struct{
  2. ID string
  3. Name string
  4. Address string
  5. }
  6. func main(){
  7. var personDB map[string] PersonInfo //声明一个key=string,value=PersonInfo的map
  8. personDB = make(map[string] PersonInfo) //通过make初始化
  9. //往这个map里插入几条数据
  10. personDB["0"] = PersonInfo{"12345","Tom","Room 203,..."}
  11. personDB["1"] = PersonInfo{"1","Jack","Room 101,..."}
  12. //....
  13. //从这个map查找键为12345的信息
  14. person, ok := personDB["0"] //假设查找到,则ok=true,否则=false
  15. if ok{
  16. fmt.Println("Found person",person.Name,"with ID",person.ID)
  17. }else{
  18. fmt.Println("Did not find person")
  19. }
  20. }
  1. //执行结果:
  2. Found person Tom with ID 12345

11.1map的声明

  1. 上面的样例假设看不懂的话没关系,以下就介绍下map的使用
  2. map的声明基本上没有多余的元素,形如:
  3. var 变量名 map[key的类型] value的类型

11.2map的创建

  1. (1)通过make()函数创建
  1. var myMap map[int] string
  2. myMap = make(map[int]string) //也能够简写成一条语句: myMap := make(map[int]string)
  3. myMap[0] = "1" //赋值
  4. myMap[1] = "2"
  5. result,_ := myMap[0] //这里用到了匿名变量
  6. fmt.Println("myMap[0]=",result)
  7. fmt.Println("myMap[1]=",myMap[1])
  1. //执行结果:
  2. myMap[0]= 1
  3. myMap[1]= 2

  1. 通过make创建的时候,还能够指定其初始容量
  2. myMap2 := make(map[int]string,100)
  3. (2)方式2,通过{}赋值的方式创建
  1. myMap3 := map[int]string{
  2. 0:"张三",
  3. 1:"李四",
  4. }
  5. fmt.Println("myMap3[0]=",myMap3[0])
  6. fmt.Println("myMap3[1]=",myMap3[1])
  1. //执行结果:
  2. myMap3[0]= 张三
  3. myMap3[1]= 李四

11.3元素的删除

  1. 通过delete()函数完毕,形如:
  2. delete(map变量名,mapkey)
  3. 假设要删除的元素没有相应的key,则什么都不发生,可是假设传入的map变量的值是 nil
  4. 该调用将导致程序抛出异常(panic)。

11.4元素的查找

  1. map通过key查找,能够返回2个变量,第一个为相应key的值,第二个为是否查找成功的bool,形如:
  1. value,ok := map[key]
  2. if ok{
  3. //找到了,处理value
  4. }else{
  5. //未找到
  6. }
  1. 当然,假设你很确定该key一定能够找到相应的值的话,那就能够直接使用一个变量来接收,比如:
  2. value := map[key]
  3. 或者,第二个參数用匿名參数来接收,比如:
  4. value,_ := map[key]

11.5元素的遍历

  1. (1)使用for循环遍历
  1. myMap := make(map[int]int)
  2. myMap[0] = 100
  3. myMap[1] = 101
  4. myMap[2] = 102
  5. for i:=0;i<len(myMap);i++ {
  6. fmt.Println("key=",i," value=",myMap[i])
  7. }
  1. 执行结果:
  2. key= 0 value= 100
  3. key= 1 value= 101
  4. key= 2 value= 102

  1. (2)使用for循环结合range关键字遍历
  1. myMap := map[int]int{
  2. 0 : 10,
  3. 1 : 20,
  4. 2 : 30,
  5. }
  6. for k,v := range myMap{
  7. fmt.Println("key=",k," value=",v)
  8. }
  1. 执行结果:
  2. key= 0 value= 10
  3. key= 1 value= 20
  4. key= 2 value= 30

Go语言学习(四)经常使用类型介绍的更多相关文章

  1. Swift语言指南(四)--类型安全和类型推断

    原文:Swift语言指南(四)--类型安全和类型推断 Swift是一门类型安全语言,类型安全语言需要代码里值的类型非常明确.如果你的代码中有部分值需要String类型,你就不能错误地传递Int. 鉴于 ...

  2. RabbitMQ四种交换机类型介绍

    RabbitMQ  原文地址: https://baijiahao.baidu.com/s?id=1577456875919174629&wfr=spider&for=pc 最新版本的 ...

  3. 智能合约语言 Solidity 教程系列1 - 类型介绍

    现在的Solidity中文文档,要么翻译的太烂,要么太旧,决定重新翻译下.尤其点名批评极客学院名为<Solidity官方文档中文版>的翻译,机器翻译的都比它好,大家还是别看了. 写在前面 ...

  4. Dart语言学习(五)Dart Bool类型

    Dart Bool类型和其他语言类似,比较简单 其特点有: 1.使用 bool 表示布尔类型 2.布尔值只有 true 和 false 3.布尔类型bool默认值是null bool isTrue = ...

  5. C语言学习总结(三) 复杂类型

    第五章.复杂数据类型 (数组.字符串.指针.结构体.枚举.共同体) 1.什么是数组? 概念:把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组: 按数组元素的类型不 ...

  6. mysql分区表之二:MySQL的表的四种分区类型介绍

    一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了.如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区 ...

  7. Go语言学习笔记(9)——接口类型

    接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口. /* 定义接口 */ type interface_name in ...

  8. 【原创】go语言学习(十三)struct介绍2

    目录: 方法的定义 函数和方法的区别 值类型和指针类型 面向对象和继承 结构体和json序列化 方法的定义 1.和其他语言不一样,Go的方法采⽤用另外一种方式实现. package main impo ...

  9. 初步swift语言学习笔记2(可选类型?和隐式可选类型!)

    作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/28904115 转载请注明出处 假设认为文章对你有所帮助.请通过留言 ...

随机推荐

  1. SharePoint 2013 创建 Site Collection

    在之前的文章中,通过SharePoint Central Administration 创建了Web Application.在这篇文章中将继续SharePoint 2013之旅——还是以Step B ...

  2. SharePoint 2013 创建Web Application

    今天继续SharePoint 2013 的探索之旅,之前几篇文章分析了SharePoint 2013的物理拓扑结构,安装,以及逻辑体系结构.在这篇文章中,我将继续Step By Step形式演示如何在 ...

  3. matlab入门笔记(一):常用快捷键

    摘自<matlab从入门到精通>胡晓东 matlab命令窗口常用快捷键与命令 matlab的工作空间和变量编辑窗口 搜索命令help和look for

  4. Java多线程框架Executor详解

       原文链接  http://www.imooc.com/article/14377 为什么引入Executor线程池框架new Thread()的缺点 每次new Thread()耗费性能调用ne ...

  5. 【转】linux中执行外部命令提示" error while loading shared libraries"时的解决办法

    今天在Centos下编译kapar 后执行时出错,老说: [root@dc01 ~]# kapar kapar: error while loading shared libraries: libsc ...

  6. Spring+Mybatis整合过程中找不到.properties文件

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' ...

  7. IOS团队开发之——CocoaPods 第三方库管理工具

    使用前需要下载ruby 的gem 命令镜像,mac 下自带有.但一般不用,直接访问国外网站有限制. 下面安装 http://ruby.taobao.org/ http://blog.devtang.c ...

  8. 修复 dji spark 的 micro sd/tf 存储卡里不能正常播放的视频文件

    可能是因为 1.在没有正确的操作停止录像前,关掉了 spark 的电源 2.在 spark 没有完成视频存储前,关掉了 spark 的电源 总之在电脑里想查看存储卡里的视频时,发现居然无法播放,这就太 ...

  9. 配置并使用Android支持的库

    原文链接:http://android.eoe.cn/topic/android_sdk Android Support Library(支持库)提供了包含一个API库的JAR文件,当你的应用运行在A ...

  10. 如何使用好android的可访问性服务(Accessibility Services)

    原文:http://android.eoe.cn/topic/android_sdk * 主题* Manifest声明和权限 可访问性服务声明 可访问性服务配置 AccessibilityServic ...