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语言虽支持递归函数,但得设置退出条件,否则会死循环下去。
本周学习到此为止,
如有错误,欢迎指出。