Go从入门到精通——常用的辅助性内置函数
Go 常用的辅助性内置函数
Go 语言中的一些函数在安装了 Go 语言后可以直接在代码中使用,无须引用任何包,这些函数叫作内置函数(built-in function)。内置函数往往是编程时大多数情况下都会使用到的函数。
1、 内置的输出信息函数 print 与 println
package main // 内置函数 println func main() { a := 10 println("a=", a) }
上述代码使用了内置函数 println 代替了我们常用的 fmt.Println 函数。两者功能基本相同,都会将其中的参数逐个输出,输出的各个参数之间会有一个空格字符。另外,与此类似,内置的 print 函数与 fmt.Print 函数功能也是基本相同,区别是内置的 print 函数不会在最后多输出一个回车换行符。
使用内置函数 println 和 print 的好处显而易见:不用引用任何包,并且代码编译更简单;但是也有一定的风险,因为 Go 语言官方文档中声明的这几个函数一般用于内部测试,不保证随着 Go 语言的版本升级会始终提供。一旦不提供,将意味着大量的代码修改工作,因此建议大家使用 fmt 包中的 Println 或 Print 函数。
2、 获取数据长度的 len 函数
len 函数一般用于获取字符串数据的长度或者切片(数组)、映射等复合结构中数据项的个数。
例如:
package main import ( "fmt" ) func main() { fmt.Println(len("How are you?")) }
len 的参数也可以是一个变量,比如:
package main import ( "fmt" ) func main() { var s string s = "How are you?" c := len(s) fmt.Println(c) }
但是,如果 len("我们都是中国人!"),len 函数中传入的中文字符串作为参数,会发现结果与我们预期的不同。
程序示例如下:
package main import ( "fmt" ) func main() { fmt.Println(len("我们都是中国人!")) }
运行该代码会发现,虽然该字符串中共有 7 个汉子 + 1个中文标点符号,但是输出的结果却是24。这是因为 len 函数获得的字符串长度是按其所占的字节数量,而 Go 语言中的字符串默认为 UTF-8 编码,汉子一般都需要占用 3 个字符,8 * 3 = 24。因此实际长度是 24。如果想要获得实际汉字字符的长度,需要将字符串转换为 rune 类型的切片变量。
package main import ( "fmt" ) func main() { fmt.Println(len([]rune("我们都是中国人!"))) }
将上面的字符串转换成 []rune 类型,也就是 rune 类型的切片,因此可以正确地输出结果 8。
3、 获取变量容量的 cap 函数
内置函数 cap 与 len 函数用法类似,但是不能用于字符串和映射变量,只能用于切片变量,返回的结果是该切片的容量,而非目前实际已有的数据项数。
4、 用于复合类型数据的操作函数
对于切片类型和映射类型等复合类型数据,可以使用 make 函数进行内存分配和初始化,make 函数就是处理复合类型数据重要的内置函数之一。
另外,对于结构类型和自定义数据类型的数据,还可以使用 new 函数新建数据类型变量(指针)。
copy 函数主要用于复制切片:
package main import ( "fmt" ) func main() { var slice1 = []int{1, 2, 3, 4, 5} slice2 := make([]int, 6) fmt.Println(slice2) copy(slice2, slice1) fmt.Println(slice2) }
- 声明定义 slice1 是一个 int 类型的切片,并且在声明的同时为它赋予了 5 个数字项的初值;
- slice2 也是 int 类型的切片,使用 make 函数分配了 6 个数值项的空间;
- 向终端打印 slice2 值;
- copy 函数第一个参数是复制动作的目标,第二个参数是复制动作的源,因此 copy(slice2,slice1)这条语句的作用是将 slice1 中的所有数值复制到 slice2 中,由于 slice1 比 slice2的长度小,因此将只复制 slice1 中 5 个数值到 slice2 中,并从 sliace2 的第一个位置开始。slice2 的最后一个项将保持初始化时的零值(对于 int 类型即整数 0)。
- 向终端打印 slice2 值,可以对比看到,在用 copy 函数前全是零值,这是用 make 函数初始化分配空间之后的正常情况;在用 copy 函数复制 slice1 中内容之后,slice2 的前 5 项与 slice1 中的内容相同,而最后一项还是 0,这说明 copy 函数正常完成了复制。
copy 函数也可以直接复制一个子切片到复制目标中,因为子切片也是切片:
package main import ( "fmt" ) func main() { var slice1 = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} slice2 := make([]int, 6) fmt.Println(slice2) n := copy(slice2, slice1[6:]) fmt.Println(n) fmt.Println(slice2) }
- 声明并定义 slice1 为 int 类型,同时赋予它 10 个数值;
- 短声明的方式赋值 slice2 为 int 类型 ,使用 make 函数分配了 6 个数值项的空间;
- 向终端输出打印 slice2 的值。由于 slice 是 make 函数初始化分配空间的,所以值为对应 int 类型的零值;
- 短声明创建n,调用 copy 函数时,我们在第二个参数中传入了 slice1 的子切片 slice1[6:],表示截取从序号 6 开始直至末尾的子切片,由于序号是从 0 开始计数,因此序号为 6 的数值为 8,截取后的子切片应为包含 7、8、9、10 四项的切片。
- copy 函数会将实际复制的数值项个数作为返回值返回,因此 n 的数值应该为 4。
可以发现结果完全符合预期。
delete 函数主要用于删除映射类型变量中的键值对,只需要提供键名作为参数即可:
package main import ( "fmt" ) func main() { var map1 = map[string]string{"Name1": "Tom", "Name2": "Mary", "Name3": "Peter"} fmt.Println(map1) delete(map1, "Name3") fmt.Println(map1) }
5、用于处理异常的函数
大多数编程语言都有在程序中出现异常情况时的处理机制,Go 语言的异常处理机制比较特殊。这里不展开具体讨论。