深度剖析Golang中的数组,字符串和切片

目录
  • 1. 数组
    • 1.1 定义数组
    • 1.2 访问数组
    • 1.3 修改数组
    • 1.4 数组长度
    • 1.5 遍历数组
    • 1.6 多维数组
  • 2. 切片
    • 2.1 定义切片
    • 2.2 访问切片元素
    • 2.3 修改切片元素
    • 2.4 切片长度和容量
    • 2.5 向切片中添加元素
    • 2.6 切片的切片
    • 2.7 切片排序
  • 3. 字符串
    • 3.1 访问字符串中的字符
    • 3.2 字符串切片
    • 3.3 字符串操作
    • 3.4 关于字符串的常见问题
  • 4. 总结

1. 数组

数组是 Golang 中的一种基本数据类型,用于存储固定数量的同类型元素。在 Golang 中,数组的长度是固定的,并且必须在定义数组时指定。

1.1 定义数组

在 Golang 中,可以使用以下语法声明数组:

var 数组名称 [数组长度]数据类型

例如,要声明一个由 5 个整数组成的数组,可以使用以下代码:

var arr [5]int

上面的代码定义了一个名为 arr 的数组,包含 5 个整数元素。可以使用以下方式初始化数组中的元素:

arr := [5]int{1, 2, 3, 4, 5}

上面的代码定义了一个名为arr的数组,包含 5 个整数元素。元素的值分别为 1、2、3、4 和 5。

我们也可以在声明期间为数组进行初始化,方法是为其元素提供值。例如,要初始化一个由 3 个字符串组成的数组,可以使用以下代码:

var names [3]string = [3]string{"Alice", "Bob", "Charlie"}

1.2 访问数组

可以使用索引运算符([])来访问数组中的元素。数组中的第一个元素的索引为 0,最后一个元素的索引为长度 -1。例如,可以使用以下方式访问数组中的元素:

  arr := [5]int{1, 2, 3, 4, 5}
  fmt.Println(arr[0]) // 输出1
  fmt.Println(arr[1]) // 输出2
  fmt.Println(arr[2]) // 输出3

上面的代码输出了数组中的前三个元素。

1.3 修改数组

可以使用以下方式修改数组中的元素:

  arr := [5]int{1, 2, 3, 4, 5}
  arr[0] = 10
  fmt.Println(arr) // 输出[10 2 3 4 5]

上面的代码将数组中的第一个元素修改为 10,并输出了修改后的数组。

1.4 数组长度

在 Golang 中,可以使用 len 函数获取数组的长度。例如,以下代码获取数组 arr 的长度:

  arr := [5]int{1, 2, 3, 4, 5}
  length := len(arr)
  fmt.Println(length) // 输出5

1.5 遍历数组

可以使用 for 循环遍历数组中的元素。例如,以下代码遍历了数组 arr 中的元素:

  arr := [5]int{1, 2, 3, 4, 5}
  for i := 0; i  lt; len(arr); i++ {
        fmt.Println(arr[i])
  }

上面的代码输出了数组中的所有元素。

1.6 多维数组

Golang 还支持多维数组。以下是一个定义和初始化二维数组的示例:

  var arr [3][3]int
  arr = [3][3]int{
       {1, 2, 3},
       {4, 5, 6},
       {7, 8, 9},
  }
  fmt.Println(arr)

上面的代码定义了一个 3x3 的二维数组,并初始化了数组中的所有元素。可以使用以下方式访问数组中的元素:

  fmt.Println(arr[0][0]) // 输出1
  fmt.Println(arr[0][1]) // 输出2
  fmt.Println(arr[1][0]) // 输出4
  fmt.Println(arr[2][2]) // 输出9

当我们知道要存储的元素数量并且在运行时不需要更改数组的大小时,数组非常有用。但是,在需要更灵活的数据类型以动态更改其大小时,我们就需要使用切片。

2. 切片

切片是 Golang 中一种灵活的数据结构,用于处理可变长度的元素集合。切片是由底层数组、长度和容量组成的。切片的长度表示切片中元素的数量,容量表示切片所引用的底层数组中元素的数量。

2.1 定义切片

切片是建立在数组之上的动态数据结构。可以使用以下语法声明切片:

var 切片名称 []数据类型

例如,要声明一个整数切片,可以使用以下代码:

  var slice []int

上面的代码定义了一个名为 slice 的切片,不包含任何元素。

可以使用以下方式初始化切片中的元素:

  slice := []int{1, 2, 3, 4, 5}

上面的代码定义了一个名为 slice 的切片,包含 5 个整数元素。元素的值分别为 1、2、3、4 和 5。

2.2 访问切片元素

可以使用以下方式访问切片中的元素:

  slice := []int{1, 2, 3, 4, 5}
  fmt.Println(slice[0]) // 输出1
  fmt.Println(slice[1]) // 输出2
  fmt.Println(slice[2]) // 输出3

上面的代码输出了切片中的前三个元素。

2.3 修改切片元素

可以使用以下方式修改切片中的元素:

  slice := []int{1, 2, 3, 4, 5}
  slice[0] = 10
  fmt.Println(slice) // 输出[10 2 3 4 5]

上面的代码将切片中的第一个元素修改为 10,并输出了修改后的切片。

2.4 切片长度和容量

可以使用 len 函数获取切片的长度,使用 cap 函数获取切片的容量。例如,以下代码获取切片 slice 的长度和容量:

  slice := []int{1, 2, 3, 4, 5}
  length := len(slice)
  capacity := cap(slice)
  fmt.Println(length) // 输出5
  fmt.Println(capacity) // 输出5

注意,这里的容量等于长度,因为我们没有指定底层数组的长度。

2.5 向切片中添加元素

可以使用 append 函数向切片中添加元素。例如,以下代码向切片 slice 中添加一个元素 6:

  slice := []int{1, 2, 3, 4, 5}
  slice = append(slice, 6)
  fmt.Println(slice) // 输出[1 2 3 4 5 6]

上面的代码将 6 添加到 slice 的末尾。

我们还可以一次性向切片中添加多个元素。例如,要向 “slice” 切片中添加整数 7、8 和 9,可以使用以下代码:

  slice = append(slice, 7, 8, 9)

2.6 切片的切片

由于切片是动态的,因此可以轻松地将其传递给函数,并且不需要指定其大小。这使切片更加强大的一个重要特性是切片表达式。切片表达式是一个从切片中选择子序列的方法,其语法如下:

切片名称[开始索引:结束索引]

这将返回一个包含从开始索引到结束索引之间的元素的新切片。例如,要从 “numbers” 切片中选择索引为 1 到索引为 3 的元素,可以使用以下代码:

  var subSlice = numbers[1:4]

注意,切片表达式中的开始索引包含在结果中,但结束索引不包含在结果中。在上面的例子中,结果将包含 “numbers” 切片中的第二、第三和第四个元素。

切片表达式还具有可选参数,它指定切片的最大容量。如果切片表达式为:

切片名称[开始索引:结束索引:最大容量]

则结果切片的容量将为最大容量-开始索引。这使得可以创建“截断”的切片,该切片不包含在开始索引和结束索引之间的任何元素,但可以容纳其他元素。

2.7 切片排序

Golang 中的 sort 包提供了多种排序算法,可以用于对切片进行排序。以下是一个对切片进行排序的示例:

  slice := []int{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}
  sort.Ints(slice)
  fmt.Println(slice) // 输出[1 1 2 3 3 4 5 5 5 6 9]

上面的代码使用 Ints 函数对整数切片进行排序,并输出排序后的结果。

3. 字符串

字符串是不可变的字节序列。在 Golang 中,字符串是用双引号括起来的字符序列。例如,以下是一个字符串变量的声明:

  var str string = "hello world"

与数组和切片不同,字符串不是一个内置类型。实际上,字符串是由字节数组表示的切片。由于字符串是不可变的,因此必须使用切片来操作它们。

3.1 访问字符串中的字符

要访问字符串中的字符,可以使用索引运算符。例如,以下代码将输出字符串 “hello world” 的第一个字符:

  fmt.Println(str[0])

字符串中的每个字符都由一个字节表示。因此,访问字符串中的字符将返回该字节的ASCII码值。

3.2 字符串切片

我们可以使用切片表达式来创建新的字符串切片。例如,以下代码将创建一个新的字符串切片,其中包含字符串 “hello world” 的前 5 个字符:

  var subStr = str[:5]

请注意,与切片一样,开始索引是包含在结果中的,但结束索引不包含在结果中。

3.3 字符串操作

Golang 提供了一些内置的字符串函数,使字符串操作更加方便。以下是其中一些常用的函数:

  • len():返回字符串的长度
  • strings.Contains():检查字符串中是否包含指定的子字符串
  • strings.Replace():将字符串中的指定子字符串替换为另一个字符串
  • strings.Split():将字符串拆分为子字符串的切片
  • strings.ToUpper() 和 strings.ToLower():将字符串中的字符转换为大写或小写

例如,以下代码使用 “strings.Contains” 函数检查字符串 “hello world” 是否包含子字符串 “world”:

  var contains = strings.Contains(str, "world")
  fmt.Println(contains) // 输出 true

3.4 关于字符串的常见问题

在 Golang 中,处理字符串时可能会遇到一些常见问题。以下是一些常见问题和解决方法:

3.4.1 如何将字符串转换为整数?

在 Golang 中,可以使用 strconv 包中的 Atoi 函数将字符串转换为整数。例如,以下代码将字符串 "123" 转换为整数 123:

  import "strconv"
  str := "123"
  num, err := strconv.Atoi(str)
  if err != nil {
        fmt.Println("转换错误")
  } else {
        fmt.Println(num)
  }

如果字符串不能转换为整数,则 Atoi 函数将返回一个错误。

3.4.2 如何将整数转换为字符串?

可以使用 strconv 包中的 Itoa 函数将整数转换为字符串。例如,以下代码将整数 123 转换为字符串 "123":

  import "strconv"
  num := 123
  str := strconv.Itoa(num)
  fmt.Println(str)

3.4.3 如何检查字符串是否为空?

可以使用 len 函数检查字符串是否为空。例如,以下代码检查字符串是否为空:

  str := ""
  if len(str) == 0 {
        fmt.Println("字符串为空")
  }

3.4.4 如何检查字符串是否包含另一个字符串?

可以使用 strings 包中的 Contains 函数检查一个字符串是否包含另一个字符串。例如,以下代码检查字符串 "hello world" 是否包含字符串 "world":

  import "strings"
  str := "hello world"
  if strings.Contains(str, "world") {
        fmt.Println("包含字符串world")
  }

3.4.5 如何比较两个字符串?

可以使用 “==” 运算符比较两个字符串是否相等。例如,以下代码比较字符串 "hello" 和字符串 "hello":

  str1 := "hello"
  str2 := "hello"
  if str1 == str2 {
        fmt.Println("字符串相等")
  }

3.4.6 如何将字符串拆分为子字符串?

可以使用 strings 包中的 Split 函数将字符串拆分为子字符串。例如,以下代码将字符串 "hello,world" 拆分为 "hello" 和 "world":

  import "strings"
  str := "hello,world"
  arr := strings.Split(str, ",")
  fmt.Println(arr)

3.4.7 如何将字符串转换为字节数组?

可以将字符串强制转换为 []byte 类型,这将返回一个包含字符串的字节数组。例如,以下代码将字符串 "hello" 转换为字节数组:

  str := "hello"
  bytes := []byte(str)
  fmt.Println(bytes)

3.4.8 如何将字节数组转换为字符串?

可以使用 string 函数将字节数组转换为字符串。例如,以下代码将字节数组 []byte{104, 101, 108, 108, 111} 转换为字符串 "hello":

  bytes := []byte{104, 101, 108, 108, 111}
  str := string(bytes)
  fmt.Println(str)

4. 总结

数组、字符串和切片是 Golang 中重要的数据结构。数组是一组固定大小的数据元素的集合,可以直接访问和修改数组中的元素。字符串是一个不可变的字节序列,可以通过下标访问字符串中的字节。切片是一个动态数组,可以根据需要动态增加或缩小大小。切片提供了方便的操作函数和语法,例如向切片中添加元素、获取切片的长度和容量、对切片进行排序等。

在 Golang 中,数组、字符串和切片的使用非常广泛,因此理解和掌握它们的基本操作和语法非常重要。同时,也需要了解它们在 Golang 中的特点和优势,例如切片可以避免数组长度不足或过长的问题,字符串可以直接使用Unicode 编码等。

以上就是深度剖析Golang中的数组,字符串和切片的详细内容,更多关于Golang数组 字符串 切片的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅谈Go语言中字符串和数组

    go语言里边的字符串处理和PHP还有java 的处理是不一样的,首先申明字符串和修改字符串 复制代码 代码如下: package main import "fmt" var name string           //申明一个字符串 var emptyname string = "" //申明一个空字符串 func main() {  //申明多个字符串并且赋值  a, b, v := "hello", "word", &

  • 简单谈谈Golang中的字符串与字节数组

    前言 字符串是 Go 语言中最常用的基础数据类型之一,虽然字符串往往都被看做是一个整体,但是实际上字符串是一片连续的内存空间,我们也可以将它理解成一个由字符组成的数组,Go 语言中另外一个与字符串关系非常密切的类型就是字节(Byte)了,相信各位读者也都非常了解,这里也就不展开介绍. 我们在这一节中就会详细介绍这两种基本类型的实现原理以及它们的转换关系,但是这里还是会将介绍的重点主要放在字符串上,因为这是我们接触最多的一种基本类型并且后者就是一个简单的 uint8 类型,所以会给予 string

  • Golang 字符串与字节数组互转的实现

    目录 一.字符串与字节数组? 二.详细代码 1.字节转字符串 2.字符串转字节数组 3.完整运行测试 总结 一.字符串与字节数组? 字符串是 Go 语言中最常用的基础数据类型之一,本质上是只读的字符型数组,虽然字符串往往都被看做是一个整体,但是实际上字符串是一片连续的内存空间. Go 语言中另外一个类型字节(Byte).在ASCII中,一个英文字母占一个字节的空间,一个中文汉字占两个字节的空间.英文标点占一个字节,中文标点占两个字节.一个Byte数组中的元素对应一个ASCII码. 二.详细代码

  • Go语言中切片使用的注意事项小结

    前言 Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一个切片变量,s := make([]int, 5, 10),即为指向了一个最大长度为10的底层数组,目前切片s使用到的长度为5. 在使用切片的时候,有几个注意事项,下面来一起看看吧. 使用append 先看一个例子: // 创建一个整型切片 // 其长度和容量都是 5 个元素 slice :=

  • 浅谈golang slice 切片原理

    slice介绍 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数据结构无法完全满足开发者的真实需求.在初始定义数组时,我们并不知道需要多大的数组,因此我们就需要"动态数组".在Go里面这种数据结构叫slice,slice并不是真正意义上的动态数组,而是一个引用类型.slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度,它是可变长的,可以随时往slice里面加数据. 初看起来,数组切片就像一个指向数组的指针,实际

  • Go语言实现字符串切片赋值的方法小结

    前言 在所有编程语言中都涉及到大量的字符串操作,可见熟悉对字符串的操作是何等重要.本文通过示例详细介绍了Go语言实现字符串切片赋值的方法,感兴趣的朋友们跟着小编一起来看看吧. 1. 在for循环的range中 func StrRangeTest() { str := []string{"str1", "str2", "str3"} for i, v := range str { fmt.Println(i, v) v = "test&q

  • 深度剖析Golang中的数组,字符串和切片

    目录 1. 数组 1.1 定义数组 1.2 访问数组 1.3 修改数组 1.4 数组长度 1.5 遍历数组 1.6 多维数组 2. 切片 2.1 定义切片 2.2 访问切片元素 2.3 修改切片元素 2.4 切片长度和容量 2.5 向切片中添加元素 2.6 切片的切片 2.7 切片排序 3. 字符串 3.1 访问字符串中的字符 3.2 字符串切片 3.3 字符串操作 3.4 关于字符串的常见问题 4. 总结 1. 数组 数组是 Golang 中的一种基本数据类型,用于存储固定数量的同类型元素.在

  • 深度剖析Golang如何实现GC扫描对象

    目录 扫描的目的 扫描的实现 运行期内存分配 运行扫描阶段 总结 之前阐述了 golang 垃圾回收通过保证三色不变式来保证回收的正确性,通过写屏障来实现业务赋值器和 gc 回收器正确的并发的逻辑.其中高概率的提到了“扫描队列”和“扫描对象”.队列这个逻辑非常容易理解,那么”扫描对象“ 这个你理解了吗?有直观的感受吗?这篇文章就是要把这个扫描的过程深入剖析下. 扫描的东西是啥?形象化描述下 怎么去做的扫描?形象化描述下 我们就是要把这两个抽象的概念搞懂,不能停留在语言级别浅层面,要知其然知其所以

  • 示例剖析golang中的CSP并发模型

    目录 1. 相关概念: 2. CSP (通信顺序进程) 3. channel:同步&传递消息 4. goroutine:实际并发执行的实体 5. golang调度器 1. 相关概念: 用户态:当一个进程在执行用户自己的代码时处于用户运行态(用户态) 内核态:当一个进程因为系统调用陷入内核代码中执行时处于内核运行态(内核态),引入内核态防止用户态的程序随意的操作内核地址空间,具有一定的安全保护作用.这种保护模式是通过内存页表操作等机制,保证进程间的地址空间不会相互冲突,一个进程的操作不会修改另一个

  • Python 中的反转字符串reversed(),切片

    目录 一.使用核心 Python 工具反转字符串 二.通过切片反转字符串 三.使用.join()和反转字符串reversed() 四.手动生成反转字符串 五.反转循环中的字符串 六.用递归反转字符串 七.反向遍历字符串 八.该reversed()内置功能 九.切片运算符, [::-1] 十.创建自定义可逆字符串 十一.以相反的顺序对 Python 字符串进行排序 当我们经常在代码中使用 Python 字符串时,您可能需要以相反的顺序使用它们.Python 包含一些方便的工具和技术,可以在这些情况

  • Python 中的反转字符串reversed(),切片

    目录 一.使用核心 Python 工具反转字符串 二.通过切片反转字符串 三.使用.join()和反转字符串reversed() 四.手动生成反转字符串 五.反转循环中的字符串 六.用递归反转字符串 七.反向遍历字符串 八.该reversed()内置功能 九.切片运算符, [::-1] 十.创建自定义可逆字符串 十一.以相反的顺序对 Python 字符串进行排序 当我们经常在代码中使用 Python 字符串时,您可能需要以相反的顺序使用它们.Python 包含一些方便的工具和技术,可以在这些情况

  • 深度剖析Java中的内存原型及工作原理

    本文主要通过分析Java内存分配的栈.堆以以及常量池详细的讲解了其的工作原理. 一.java虚拟机内存原型 寄存器:我们在程序中无法控制栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中堆:存放用new产生的数据静态域:存放在对象中用static定义的静态成员常量池:存放常量非RAM存储:硬盘等永久存储空间. 二.常量池(constant pool) 常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据.除了包含代码中所定义的各种基本类型(如int.

  • 轻松读懂Golang中的数组和切片

    目录 一.数组和切片的区别是什么? 1.数组 2.切片 二.数组和切片的初始化? 1.数组 2.切片 二.常见问题 1.切片的初始化与追加 2.slice拼接问题 3.new和make的区别 总结 一.数组和切片的区别是什么? 1.数组 数组是内置(build-in)类型,是一组同类型数据的集合,它是值类型,通过从0开始的下标索引访问元素值.在初始化后长度是固定的,无法修改其长度.当作为方法的参数传入时将复制一份数组而不是引用同一指针.数组的长度也是其类型的一部分,通过内置函数len(array

  • 深度剖析java中JDK动态代理机制

    摘要 相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象. 代理模式 使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用分派到目标对象上反射执行,还可以在分派过程中添加"前置通知"和后置处理(如在调用目标方法前校验权限,在调用完目标方法后打印日志等)等功能. 使用动态代理的五大步骤 1.通过实现InvocationHandler接口来自定义自己的Invocati

  • Golang 中整数转字符串的方法

    整形转字符串经常会用到,本文讨论一下 Golang 提供的这几种方法.基于 go1.10.1 fmt.Sprintf fmt 包应该是最常见的了,从刚开始学习 Golang 就接触到了,写 'hello, world' 就得用它.它还支持格式化变量转为字符串. func Sprintf(format string, a ...interface{}) string Sprintf formats according to a format specifier and returns the re

  • Golang中Bit数组的实现方式

    Go语言里的集合一般会用map[T]bool这种形式来表示,T代表元素类型.集合用map类型来表示虽然非常灵活,但我们可以以一种更好的形式来表示它. 例如在数据流分析领域,集合元素通常是一个非负整数,集合会包含很多元素,并且集合会经常进行并集.交集操作,这种情况下,bit数组会比map表现更加理想. 一个bit数组通常会用一个无符号数或者称之为"字"的slice来表示,每一个元素的每一位都表示集合里的一个值.当集合的第i位被设置时,我们才说这个集合包含元素i. 下面的这个程序展示了一个

随机推荐