• 爱上开源之golang入门至实战第四章函数(Func)(五)


    爱上开源之golang入门至实战第四章函数(Func)(五)

    4.4.5 变长参数

     

    变长参数传递的函数在很多语言里都是支持的,javascript里就有这样的函数, java在1.5以后也开始支持, 同样在go语言里也支持这样非常方便的变长参数的函数。 比如,我们最常用到的fmt.Println(), 见print.go源文件

    1. // Println formats using the default formats for its operands and writes to standard output.
    2. // Spaces are always added between operands and a newline is appended.
    3. // It returns the number of bytes written and any write error encountered.
    4. func Println(a ...any) (n int, err error) {
    5. return Fprintln(os.Stdout, a...)
    6. }

    如上段源代码,Println函数就是变长参数的函数, ...any,表示数据类型为any的变参数;

    下面我们示例一段变长参数的函数的例子

    1. func Average(n ...int) float64 {
    2. if len(n) == 0 {
    3. return 0
    4. }
    5. sum := 0.0
    6. for _, v := range n {
    7. sum += float64(v)
    8. }
    9. return sum / float64(len(n)*1.0)
    10. }

    1. fmt.Printf("Average()=%v \n", Average())
    2. fmt.Printf("Average(1)=%v \n", Average(1))
    3. fmt.Printf("Average(1, 6)=%v \n", Average(1, 6))
    4. fmt.Printf("Average(1, 2, 3, 4, 5)=%v \n", Average(1, 2, 3, 4, 5))
    5. n := append(make([]int, 0), 2, 4, 6, 8, 10, 12)
    6. fmt.Printf("Average(%v)=%v \n", n, Average(n...))
    7. ==== OUTPUT ====
    8. Average()=0
    9. Average(1)=1
    10. Average(1, 6)=3.5
    11. Average(1, 2, 3, 4, 5)=3
    12. Average([2 4 6 8 10 12])=7

    变长函数的最后一个参数是采用 ...type 的形式,那么这个函数就可以处理一个变长的参数,这个长度可以为 0,这样的函数称为变参函数。如上个例子,我们就定义了一个Average的变长参数的函数,Average函数参数定义为...int,表示处理一个int类型的变长参数,函数的实现,是变量所有的参数,然后累加计算平均值。 再来看看函数的调用。

    Average(), 参数为0个参数

    Average(1), 参数为1个参数

    Average(1,6), 参数为2个参数

    Average(1, 2, 3, 4, 5), 参数为5个参数

    Average(n...), 参数为6个参数

    注意最后一个调用参数的方式, Average(n...) n是一个数组或者是切片,可以通过...的方式,把一个数组或者切片转换为变长的参数进行传递, 这个方式在很多源代码里都有类似的调用。

    在使用变长函数定义时要注意

    1. 一个变长参数的函数定义里,只能有一个变长的参数定义

    2. 一个变长参数的函数定义里,只能是最后一个参数定义能定义为变长的参数

    1. func Says(name string, greets ...string) {
    2. word := strings.Join(greets, " ")
    3. fmt.Printf("%s: %s\n", name, word)
    4. }

    1. func TestReturnFunc2(t *testing.T) {
    2. Says("Ginghan", "Welcome to", "Golang", "Java", "Python")
    3. words := append(make([]string, 0), "like", "Golang", "Java", "Python", "C#", "Php", "C++", "Js")
    4. Says("程序员紫龙", words...)
    5. }
    6. ==== OUTPUT ====
    7. Ginghan: Welcome to Golang Java Python
    8. 程序员紫龙: like Golang Java Python C# Php C++ Js

    在上面的例子里,定义了Says变长参数的函数; 只能最后一个参数可以定义为变长的参数,如greets ...string;

    words := append(make([]string, 0), "like", "Golang", "Java", "Python", "C#", "Php", "C++", "Js")

    这里的代码,也是一个变长参数的函数的使用例子, golang里内置的append函数也是一个变长参数的函数, 参考builtin.go代码

    1. // The append built-in function appends elements to the end of a slice. If
    2. // it has sufficient capacity, the destination is resliced to accommodate the
    3. // new elements. If it does not, a new underlying array will be allocated.
    4. // Append returns the updated slice. It is therefore necessary to store the
    5. // result of append, often in the variable holding the slice itself:
    6. // slice = append(slice, elem1, elem2)
    7. // slice = append(slice, anotherSlice...)
    8. // As a special case, it is legal to append a string to a byte slice, like this:
    9. // slice = append([]byte("hello "), "world"...)
    10. func append(slice []Type, elems ...Type) []Type

    这个append是处理切片非常常见的函数, 大家一定要熟记这个函数的用法。

    变长的方式,只能作为变长参数,不能作为返回值。

    1. func Says(name string, greets ...string) ...string {
    2. word := strings.Join(greets, " ")
    3. fmt.Printf("%s: %s\n", name, word)
    4. }
    5. ==== Complie Error ====
    6. .\build_test.go:546:43: can only use ... with final parameter in list

    编译失败!!!

     

     

  • 相关阅读:
    手把手调参最新 YOLOv7 模型 推理部分 - 最新版本(一)
    食品行业申请ISO22000认证条件、流程、资料及意义有哪些
    java接口和内部类
    物理层(2.1)
    Bias in Emotion Recognition with ChatGPT
    彻底解决python多进程can‘t pickle问题
    python爬虫(3)
    【微服务】关于WSGI Server即web服务器
    使用ipmitool配置X86服务器的BMC网络和用户信息
    一个人 三个月 干了二十万
  • 原文地址:https://blog.csdn.net/inthirties/article/details/126497857