Go中的变体功能

时钟鸟淡出Mail.ru云解决方案



团队翻译了一篇有关Go中可变参数功能的文章。它的作者解释了可变参数功能与普通功能的不同之处以及如何创建它们。



什么是可变函数



函数是旨在执行特定任务的一段代码。该函数将传递一个或多个参数,并返回一个或多个结果。



变体函数与常规函数相同,但它们可以采用无限数量或可变数量的参数。



func f(elem ...Type)


这是典型的可变参数函数语法。该运算符...(也称为装箱运算符)告诉Go将所有类型参数存储Type在parameter中elem换句话说,Go创建一个elem类型[]Type为,即切片的变量并且所有传递给函数的参数都存储在slice中elem



让我们看一个函数的例子append()



append([]Type, args, arg2, argsN)


该函数append期望第一个参数是一个切片,Type然后是任意数量的参数。但是,如何在切片中添加s2切片s1



从函数的定义append()可以看出,我们无法将两个切片传递给它-Type只有一个类型实参。因此,我们使用拆箱运算符...将切片分解为一系列参数。然后可以将它们传递给函数append



append(s1, s2...)


...表示包装操作员和拆包操作员。拆箱运算符始终出现在变量名称之后。



在我们的示例中,切片s1s2相同类型。我们通常知道函数的参数及其所使用的参数数量。函数accept如何知道已经传递了多少参数?



如果查看函数声明append,则可以看到表达式elems ...Type。它将所有参数(从第二个参数开始)打包到slice中elems



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


仅函数声明中的最后一个参数可以是可变参数。



因此,该函数的第一个参数append只是一个切片,因为它被定义为切片。所有后续参数都打包到一个名为的参数中elems



现在让我们看看如何创建自己的可变参数函数。



如何创建可变函数



如上所述,可变参数函数是一个接受可变数量参数的常规函数​​。为此,您需要使用装箱运算符...Type



让我们编写一个getMultiples具有第一个factor类型实int(乘数因子)和可变数量的其他类型实参的函数int他们将被包装成薄片args



用于make创建一个空切片,其大小与slice相同args使用循环for range,将切片元素args乘以factor我们将结果放入一个新的空片中multiples,该空片将作为函数的结果返回。



func getMultiples(factor int, args ...int) []int {
	multiples := make([]int, len(args))
	for index, val := range args {
		multiples[index] = val * factor
	}
	return multiples
}


这是一个非常简单的函数,将其应用在block中main()



func main() {
	s := []int{10, 20, 30}
	mult1 := getMultiples(2, s...)
	mult2 := getMultiples(3, 1, 2, 3, 4)
	fmt.Println(mult1)
	fmt.Println(mult2)
}




https://play.go.org/p/BgU6H9orhrn



在上面的示例中,如果您将slice sgetMultiples作为第二个参数传递给函数会发生什么情况编译器将报告一个错误:在参数中,getMultiples它不能用作s (type [] int)typeint这是因为切片的类型[]int, getMultiples需要使用来自的参数int



切片如何传递给可变参数函数



切片是对数组的引用。那么,当您使用拆箱运算符将切片传递给可变参数函数时会发生什么? Go是创建新切片args还是使用旧切片s



由于没有比较工具args == s,因此需要更改切片args。然后我们找出原始切片是否已更改s





https://play.go.org/p/fbNgVGu6JZO



在上面的示例中,我们稍微更改了功能getMultiples。而不是创建一个新的切片,我们将计算结果分配给切片的元素args,将输入的元素替换为相乘的元素。



结果,我们看到原始切片的值s已经变化。如果您通过取消装箱运算符将参数传递给可变参数函数,则Go会使用对原始数据基础的数据数组的引用来创建新切片。请注意不要出错,否则原始数据将因计算而改变。



祝好运!



还有什么要读的:



  1. Go和CPU缓存
  2. 为什么后端开发人员应该学习Go编程语言
  3. 我们有关数字化转型的电报频道



All Articles