一文学透Go语言15个的内置函数(builtin)

2023年 7月 10日 22.3k 0

学习Go语言的内置函数(built-in)。

什么是Go语言内置函数呢?

简单地理解就是指Go内置的不需要以包名为前缀就可以直接访问的函数:

//非内置函数
import "fmt"
fmt.Println("test")
//内置函数
println("test")

按目前Go最新的版本(1.20.5),Go语言总共有15个内置函数,分别为:append,new,make,len,cap,copy,delete,panic,recover,close,complex,real,imag,print,println。

append

append函数用于将一个或多个元素添加到切片(slice)的末尾,其函数签名为:

func append(slice []Type, elems ...Type) []Type

append函数第一个参数slice是一个切片,elems表示切片的元素,其数据类型与切片元素的数据类型必须相同:

s0 := []int{1, 2}

// 添加一个元素 s1 = []int{1, 2, 3}
s1 := append(s0, 3)   

 // 添加多个元素 s2 = []int{1, 2, 3, 4, 5, 6}
s2 := append(s1, 4, 5, 6)

// 将切片添加到另一个切片 s3 = []int{1, 2, 3, 4, 5, 6 , 1 , 2}
s3 := append(s2, s0...) 

 // 截取不同切片再合并 s4 = []int{[4 5 6 3 4 5 6 1 2]}
s4 := append(s3[3:6], s3[2:]...)

//空接口切片
var t []interface{}
//t == []interface{}{100, 6.8, "test"}
t = append(t, 100, 6.8, "test")   

var b []byte
// 将字符串添加字节数组 b = []byte{'j', 'u', 's','t','','g','o'}
b = append(b, "just go"...) 

append函数往切片添加元素时,如果切片的容量还没满,那么返回的新切片与源切片指向同一个底层数组:

package main

import "fmt"

func main() {

 //创建一个容量为2,长度为0的切片
 s1 := make([]int, 0, 2)

 //向s1添加两个元素
 s2 := append(s1, 3, 4)

 fmt.Printf("s1的地址:%p,容量:%d,长度:%d\n", s1, cap(s1), len(s1))
 fmt.Printf("s2的地址:%p,容量:%d,长度:%d\n", s2, cap(s2), len(s2))
}

上面代码的运行结果如下所示,可以看出两个切片指向的底层数组地址是一致的:

s1的地址:0xc0000140a0,容量:2,长度:0
s2的地址:0xc0000140a0,容量:2,长度:2

如果切片的容量已经耗尽,那么append函数会为切片重新分配一个更大容量的底层数组,并将数据复制过去,此时返回的切片则指向新分配的数组:

package main

import "fmt"

func main() {
 //创建一个容量为2,长度为0的切片
 s3 := make([]int, 0, 2)
 //向s4添加两个元素
 s4 := append(s3, 1, 2, 3, 4)

 fmt.Printf("s3的地址:%p,容量:%d,长度:%d\n", s3, cap(s3), len(s3))
 fmt.Printf("s4的地址:%p,容量:%d,长度:%d\n", s4, cap(s4), len(s4))
}

上面代码的运行结果如下,可以看到,向一个容量只有2的切片添加4个元素时,append函数会自动扩容:

s3的地址:0xc0000140c0,容量:2,长度:0
s4的地址:0xc000020080,容量:4,长度:4

new

new函数用于为指定的类型分配内存,并返回一个对应内存的指针,其函数签名如下:

func new(Type) *Type

使用new分配的一般是普通数据类型(如:intfloat32等)或复合类型(比如arraystruct):

i := new(int)
*i = 10
fmt.Println(*i) //10

type User struct{
    ID int
    Name string
}

// 下面使用new创建结构体的语句等同于 u := &User{}
u := new(User) 

make

make函数用于创建并初始化slicechannelmap这样的引用类型,其函数签名如下:

func make(t Type, size ...IntegerType) Type

new函数相似,make的第一个参数是所要定义的数据类型,而与new函数不同的是,make函数并不是返回一个指针类型,这是因为slicechannelmap是引用类型:

m := make(map[string]string)

当创建切片时,必须传入第二个参数来指定切片的长度:

s := make([]int,2)

也可以传入第三个参数来指定义切片的容量,如果不传第三个参数,则容量与长度相等:

//容量:5,长度:2
s1 := make([]int,2,5)
//未指定容量,因此容量与长度都等3
s2 := make([]string,3)

如果是创建map类型时,那么就不需要传入第二个与第三个参数了:

m := make(map[string]string)

创建channel对象时,make函数的第二个参数用于指定channel缓冲区的大小,如果没有传入,就表示创建了一个没有缓冲区的channel

//无缓冲区
c1 := make(chan int)
//缓冲区大小:2
c := make(chan int,2)

len与cap

len函数用于获得指定类型的长度,其函数签名如下:

func len(v Type) int

len函数只能用于获得数组,数组指针,切片,channel以及字符串这五种类型的长度。

如果是数组或者数组指针,len函数返回的是数组元素数量:

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

p := &a

fmt.Printf("数组长度:%d,指针数组长度:%d\n", len(a), len(p))

对于channel类型,len函数返回channel当前缓冲区元素的个数:

package main

import (
 "fmt"
 "sync"
)

func main() {
  //容量为10
 ch := make(chan int, 10)
 var w sync.WaitGroup
 w.Add(1)
 go func(ch chan int) {
  ch 

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论