Golang(4)-数据类型 - Go语言中文社区

Golang(4)-数据类型



更多关于Golang核心编程知识的文章请看:Golang核心编程(0)-目录页


Go语言内置以下这些基础类型:
布尔类型: bool 。 整型: int8 、 byte 、 int16 、 int 、 uint 、 uintptr 等。
浮点类型: float32 、 float64 。 复数类型: complex64 、 complex128 。
字符串: string 。字符类型: rune 。
错误类型: error 。
此外,Go语言也支持以下这些复合类型:
指针(pointer)数组(array) 切片(slice) 字典(map)
通道(chan)结构体(struct)接口(interface)

一、布尔类型

Go语言中的布尔类型与其他语言基本一致,关键字为bool,可赋值为预定义的 true 和false 示例代码如下:

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

二、整型

整型是所有编程语言里最基础的数据类型。Go语言支持如下所示的这些整型类型。
在这里插入图片描述

三、浮点型

浮点型用于表示包含小数点的数据,比如1.234就是一个浮点型数据。Go语言中的浮点类型采用IEEE-754标准的表达方式。

Go语言定义了两个类型 float32 和 float64 ,其中 float32 等价于C语言的 float 类型,float64 等价于C语言的 double 类型。
在Go语言里,定义一个浮点数变量的代码如下:

	var fvalue1 float32
	fvalue1 = 12
	fvalue2 := 12.0 // 如果不加小数点,fvalue2会被推导为整型而不是浮点型

四、字符串

在Go语言中,字符串也是一种基本类型。相比之下, C/C++语言中并不存在原生的字符串类型,通常使用字符数组来表示,并以字符指针来传递。
Go语言中字符串的声明和初始化非常简单,举例如下:

	var str string  // 声明一个字符串变量
	str = "Hello world" // 字符串赋值
	ch := str[0] // 取字符串的第一个字符
	fmt.Printf("The length of "%s" is %d n", str, len(str))
	fmt.Printf("The first character of "%s" is %c.n", str, ch)

输出结果为:
在这里插入图片描述

4.1、字符串操作

在这里插入图片描述

4.2、字符串遍历

Go语言支持两种方式遍历字符串。一种是以字节数组的方式遍历:

	str := "Hello,世界"
	n := len(str)
	for i := 0; i < n; i++ {
	ch := str[i] // 依据下标取字符串中的字符,类型为byte
	fmt.Println(i, ch)
}

另一种便利方法也是最常用的容器类遍历方法,使用range关键字遍历:

	str := "Hello,世界"
	for i, ch := range str {
	fmt.Println(i, ch)//ch的类型为rune
	}

五、数组

数组是Go语言编程中最常用的数据结构之一。顾名思义,数组就是指一系列同一类型数据的集合。数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数组的长度。

以下为一些常规的数组声明方法:

	[32]byte // 长度为32的数组,每个元素为一个字节
	[2*N] struct { x, y int32 } // 复杂类型数组
	[1000]*float64  // 指针数组
	[3][5]int  // 二维数组
	[2][2][2]float64  // 等同于[2]([2]([2]float64))

数组的长度是该数组类型的一个内置常量,可以用Go语言的内置函数len()来获取。下面是一个获取数组 arr 元素个数的写法:
arrLength := len(arr)

5.1、元素访问

可以使用数组下标来访问数组中的元素。与C语言相同,数组下标从0开始, len(array)-1则表示最后一个元素的下标。下面的示例遍历整型数组并逐个打印元素内容:

for i := 0; i < len(array); i++ {
	fmt.Println("Element", i, "of array is", array[i])
}

Go语言还提供了一个关键字range ,用于便捷地遍历容器中的元素。当然,数组也是range的支持范围。上面的遍历过程可以简化为如下的写法:

for i, v := range array {
	fmt.Println("Array element[", i, "]=", v)
}

在上面的例子里可以看到,range 具有两个返回值,第一个返回值是元素的数组下标,第二个返回值是元素的值。

5.2、值类型

需要特别注意的是,在Go语言中数组是一个值类型(value type)。所有的值类型变量在赋值和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该参数将发生数据复制。因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是所传入数组的一个副本

六、数组切片

Go语言提供了数组切片(slice)这个非常酷的功能来弥补数组的不足。基于数组,数组切片添加了一系列管理功能,可以随时动态扩充存放空间,并且可以被随意传递而不会导致所管理的元素被重复复制。

6.1、创建数组切片

创建数组切片的方法主要有两种——基于数组和直接创建,下面我们来简要介绍一下这两种方法。

  • 基于数组
    数组切片可以基于一个已存在的数组创建。数组切片可以只使用数组的一部分元素或者整个数组来创建,甚至可以创建一个比所基于的数组还要大的数组切片。

如何基于一个数组的前5个元素创建一个数组切片:

	var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	// 基于数组创建一个数组切片
	var mySlice []int = myArray[:5]

Go语言支持用 myArray[first:last] 这样的方式来基于数组生成一
个数组切片,而且这个用法还很灵活,比如下面几种都是合法的:

基于 myArray 的所有元素创建数组切片:
mySlice = myArray[:]
基于 myArray 的前5个元素创建数组切片:
mySlice = myArray[:5]
基于从第5个元素开始的所有元素创建数组切片:
mySlice = myArray[5:]

  • 直接创建
    并非一定要事先准备一个数组才能创建数组切片。Go语言提供的内置函数 make()可以用于灵活地创建数组切片。

创建一个初始元素个数为5的数组切片,元素初始值为0:
mySlice1 := make([]int, 5)
创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
mySlice2 := make([]int, 5, 10)
直接创建并初始化包含5个元素的数组切片:
mySlice3 := []int{1, 2, 3, 4, 5}

6.2、元素遍历

操作数组元素的所有方法都适用于数组切片,比如数组切片也可以按下标读写元素,用len()函数获取元素个数,并支持使用 range关键字来快速遍历所有元素。

传统的元素遍历方法如下:

for i := 0; i <len(mySlice); i++ {
	fmt.Println("mySlice[", i, "] =", mySlice[i])
}

使用range关键字可以让遍历代码显得更整洁。 range 表达式有两个返回值,第一个是索引,第二个是元素的值:

for i, v := range mySlice {
	fmt.Println("mySlice[", i, "] =", v)
}

6.3、动态增减元素

可动态增减元素是数组切片比数组更为强大的功能。与数组相比,数组切片多了一个存储能力(capacity)的概念,即元素个数和分配的空间可以是两个不同的值。

数组切片支持Go语言内置的cap()函数和len() 函数, cap()函数返回的是数组切片分配的空间大小,而len() 函数返回的是数组切片中当前所存储的元素个数。

6.4、追加元素

使用 append() 函数。

下面的代码可以从尾端给 mySlice 加上3个元素,从而生成一个新的数组切片:

mySlice = append(mySlice, 1, 2, 3)

函数 append() 的第二个参数其实是一个不定参数,我们可以按自己需求添加若干个元素,甚至直接将一个数组切片追加到另一个数组切片的末尾:

	mySlice2 := []int{8, 9, 10}
	// 给mySlice后面添加另一个数组切片
	mySlice = append(mySlice, mySlice2...)

需要注意的是,我们在第二个参数 mySlice2 后面加了三个点,即一个省略号,如果没有这个省略号的话,会有编译错误,因为按 append() 的语义,从第二个参数起的所有参数都是待附加的元素。因为 mySlice 中的元素类型为 int ,所以直接传递 mySlice2 是行不通的。加上省略号相当于把 mySlice2 包含的所有元素打散后传入。
上述调用等同于:
mySlice = append(mySlice, 8, 9, 10)

数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间(即 cap() 调用返回的信息),数组切片会自动分配一块足够大的内存。

七、map

在C++/Java中, map 一般都以库的方式提供,比如在C++中是STL的 std::map<> ,在C#中是Dictionary<> ,在Java中是 Hashmap<> ,在这些语言中,如果要使用 map ,事先要引用相应的库。而在Go中,使用 map 不需要引入任何库,并且用起来也更加方便。

package main
import "fmt"
// PersonInfo是一个包含个人详细信息的类型
type PersonInfo struct {
	ID string
	Name string
	Address string
}
func main() {
	var personDB map[string] PersonInfo
	personDB = make(map[string] PersonInfo)
	// 往这个map里插入几条数据
	personDB["12345"] = PersonInfo{"12345", "Tom", "Room 203,..."}
	personDB["1"] = PersonInfo{"1", "Jack", "Room 101,..."}
	// 从这个map查找键为"1234"的信息
	person, ok := personDB["1234"]
	// ok是一个返回的bool型,返回true表示找到了对应的数据
	if ok {
		fmt.Println("Found person", person.Name, "with ID 1234.")
	} else {
		fmt.Println("Did not find person with ID 1234.")
	}
}

上面这个简单的例子基本上已经覆盖了 map 的主要用法,下面对其中的关键点进行细述。

7.1、map声明

map 的声明基本上没有多余的元素,比如:

var myMap map[string] PersonInfo

其中,myMap是声明的map 变量名,string 是键的类型, PersonInfo则是其中所存放的值类型。

7.2、创建

我们可以使用Go语言内置的函数 make() 来创建一个新 map 。下面的这个例子创建了一个键类型为 string 、值类型为 PersonInfo 的 map :

myMap = make(map[string] PersonInfo)

注意,声明后的map还需要使用make()去创建才能使用。

7.3、元素赋值

赋值过程非常简单明了,就是将键和值用下面的方式对应起来即可:

myMap["1234"] = PersonInfo{"1", "Jack", "Room 101,..."}

7.4、元素删除

Go语言提供了一个内置函数 delete(),用于删除容器内的元素。下面我们简单介绍一下如何用 delete() 函数删除 map 内的元素:

delete(myMap, "1234")

上面的代码将从 myMap 中删除键为“1234”的键值对。如果“1234”这个键不存在,那么这个调用将什么都不发生,也不会有什么副作用。但是如果传入的 map 变量的值是 nil ,该调用将导致程序抛出异常(panic)。

7.5、元素查找

在Go语言中,要从 map 中查找一个特定的键,可以通过下面的代码来实现:

	value, ok := myMap["1234"]
	if ok { // 找到了
	// 处理找到的value
	}
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/pbrlovejava/article/details/83928209
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢