Go语言 3

本文详细介绍了Go语言中的结构体,包括定义、实例化和结构体指针的使用。接着讲解了切片的概念,如何创建、截取和操作切片,以及追加元素的方法。此外,还探讨了Go中的范围(range)关键字在遍历数组、切片和集合时的应用。最后,阐述了集合(Map)的创建、元素操作以及删除元素的方法。文章以实例代码辅助理解,帮助读者掌握Go语言的基础数据结构操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.结构体

结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:

type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}

实例:

package main

import "fmt"

type Books struct {
   title string
   author string
   subject string
   book_id int
}


func main() {

    // 创建一个新的结构体
    fmt.Println(Books{"Go 语言", "www.runoob.com", "Go 语言教程", 6495407})

    // 也可以使用 key => value 格式
    fmt.Println(Books{title: "Go 语言", author: "www.runoob.com", subject: "Go 语言教程", book_id: 6495407})

    // 忽略的字段为 0 或 空
   fmt.Println(Books{title: "Go 语言", author: "www.runoob.com"})
}

结果:

{Go 语言 www.runoob.com Go 语言教程 6495407}
{Go 语言 www.runoob.com Go 语言教程 6495407}
{Go 语言 www.runoob.com  0}

结构体+自定义:

package main

import "fmt"

type Dictionary struct {
	name string
	old  int
}

func main() {
	var Book1 Dictionary
	var Book2 Dictionary

	/*Book1内容*/
	Book1.name = "Fly"
	Book1.old = 10

	/*Book2内容*/
	Book2.name = "A journey to the west"
	Book2.old = 15

	printbook(Book1)
	printbook(Book2)
}

func printbook(book Dictionary) {
	fmt.Printf("name=%s\n", book.name)
	fmt.Printf("old=%d\n", book.old)
}

结果:

name=Fly
old=10                    
name=A journey to the west
old=15               

结构体指针:

package main

import "fmt"

type Dictionary struct {
	name string
	old  int
}

func main() {
	var Book1 Dictionary
	var Book2 Dictionary

	/*Book1内容*/
	Book1.name = "Fly"
	Book1.old = 10

	/*Book2内容*/
	Book2.name = "A journey to the west"
	Book2.old = 15

	printbook1(&Book1)
	printbook1(&Book2)
}
func printbook1(book *Dictionary) {
	fmt.Printf("name=%s\n", book.name)
	fmt.Printf("old=%d\n", book.old)
}

结果:

name=Fly                  
old=10                    
name=A journey to the west
old=15                    
 

2.切片

切片是对数组的抽象。由于数组的长度不可变,在特定的场景不适用,因此便有了切片。相比于数组,切片的长度是可变的,可以追加元素,在追加时可能使切片的容量增大。(感觉此处有点python的影子)

定义切片:

你可以声明一个未指定大小的数组来定义切片:

var identifier []type

切片不需要说明长度。

或使用 make() 函数来创建切片:

var slice1 []type = make([]type, len)

也可以简写为

slice1 := make([]type, len)

也可以指定容量,其中 capacity 为可选参数。

make([]T, length, capacity)

这里 len 是数组的长度并且也是切片的初始长度。

package main

import "fmt"

func main() {
	var numbers = make([]int, 5, 8) //创建切片
	number := []int{0, 1, 2} //初始化切片,此时长度和容量都为3
	printSlice(numbers)
	printSlice(number)
}

func printSlice(x []int) {
	fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}

运行结果:

len=5 cap=8 slice=[0 0 0 0 0]
len=3 cap=3 slice=[0 1 2]
 

空切片:

当设定切片的长度为0时,切片便默认为nil。

切片截取:

可以通过设置下限及上限来设置截取切片 [lower-bound:upper-bound],实例如下:

package main

import "fmt"

func main() {
   /* 创建切片 */
   numbers := []int{0,1,2,3,4,5,6,7,8}  
   printSlice(numbers)

   /* 打印原始切片 */
   fmt.Println("numbers ==", numbers)

   /* 打印子切片从索引1(包含) 到索引4(不包含)*/
   fmt.Println("numbers[1:4] ==", numbers[1:4])

   /* 默认下限为 0*/
   fmt.Println("numbers[:3] ==", numbers[:3])

   /* 默认上限为 len(s)*/
   fmt.Println("numbers[4:] ==", numbers[4:])

   numbers1 := make([]int,0,5)
   printSlice(numbers1)

   /* 打印子切片从索引  0(包含) 到索引 2(不包含) */
   number2 := numbers[:2]
   printSlice(number2)

   /* 打印子切片从索引 2(包含) 到索引 5(不包含) */
   number3 := numbers[2:5]
   printSlice(number3)

}

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

结果:

len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
len=3 cap=7 slice=[2 3 4]

append() 和 copy() 函数

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。

下面的代码描述了从拷贝切片的 copy 方法和向切片追加新元素的 append 方法。

示例:

package main

import "fmt"

func main() {
   var numbers []int
   printSlice(numbers)

   /* 允许追加空切片 */
   numbers = append(numbers, 0)
   printSlice(numbers)

   /* 向切片添加一个元素 */
   numbers = append(numbers, 1)
   printSlice(numbers)

   /* 同时添加多个元素 */
   numbers = append(numbers, 2,3,4)
   printSlice(numbers)

   /* 创建切片 numbers1 是之前切片的两倍容量*/
   numbers1 := make([]int, len(numbers), (cap(numbers))*2)

   /* 拷贝 numbers 的内容到 numbers1 */
   copy(numbers1,numbers)
   printSlice(numbers1)  
}

func printSlice(x []int){
   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

代码结果:

len=0 cap=0 slice=[]
len=1 cap=1 slice=[0]
len=2 cap=2 slice=[0 1]
len=5 cap=6 slice=[0 1 2 3 4]
len=5 cap=12 slice=[0 1 2 3 4]

3.范围

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

实例:

package main

import "fmt"

func main() {
	//用range去求一个slice的和
	nums := []int{5, 2, 1}
	sum := 0
	for _, num := range nums {
		sum += num
	}
	fmt.Printf("sum=%d\n", sum)
	sum = 0//重新赋值
	for i, num := range nums {
		if num == 1 {
			sum += num
			//i代表下标
			fmt.Printf("sum=%d,index=%d\n", sum, i)
		}
	}
}

运行结果:

sum=8
sum=1,index=2

4.集合

Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。

Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过,Map 是无序的,我们无法决定它的返回顺序,这是因为 Map 是使用 hash 表来实现的。

示例:

package main

import "fmt"

func main() {
	//声明变量,默认westmap为nil
	var westmap map[string]string
	//使用make函数
	westmap = make(map[string]string)
	westmap["师傅"] = "唐僧"
	westmap["大师兄"] = "孙悟空"
	westmap["二师兄"] = "猪悟能"
	westmap["三师弟"] = "沙悟净"
	for name := range westmap {
		fmt.Println(name, "是", westmap[name])
	}
	/*查看元素是否存在于集合内*/
	name, ok := westmap["白骨精"]
	if ok {
		fmt.Println(name, "是", westmap[name])
	} else {
		fmt.Println("白骨精不存在")
	}
}

代码结果:

师傅 是 唐僧
大师兄 是 孙悟空
二师兄 是 猪悟能
三师弟 是 沙悟净
白骨精不存在    

注:如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对

delete() 函数

delete() 函数用于删除集合的元素, 参数为 map 和其对应的 key。实例如下:

package main

import "fmt"

func main() {
	//声明变量,默认westmap为nil
	var westmap map[string]string
	//使用make函数
	westmap = make(map[string]string)
	westmap["师傅"] = "唐僧"
	westmap["大师兄"] = "孙悟空"
	westmap["二师兄"] = "猪悟能"
	westmap["三师弟"] = "沙悟净"
	for name := range westmap {
		fmt.Println(name, "是", westmap[name])
	}
	/*查看元素是否存在于集合内*/
	name, ok := westmap["白骨精"]
	if ok {
		fmt.Println(name, "是", westmap[name])
	} else {
		fmt.Println("白骨精不存在")
	}
	fmt.Println("删除二师兄")
	fmt.Println("删除后:")
	delete(westmap, "二师兄")
	for name := range westmap {
		fmt.Println(name, "是", westmap[name])
	}
}

代码结果:

师傅 是 唐僧
大师兄 是 孙悟空
二师兄 是 猪悟能
三师弟 是 沙悟净
白骨精不存在    
删除二师兄      
删除后:         
三师弟 是 沙悟净
师傅 是 唐僧    
大师兄 是 孙悟空

5.递归方法:

递归方法C已涉及并学习过,此处不再强调。

注:Go语言虽支持递归函数,但得设置退出条件,否则会死循环下去。

本周学习到此为止,

如有错误,欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值