几天前纠结了一个蛋疼的问题,在go里面函数式支持可变参数的,譬如...T,go会创建一个slice,用来存放传入的可变参数,那么,如果创建一个slice,例如a,然后以a...这种方式传入,go会不会还会新建一个slice,将a的数据全部拷贝一份过去?

如果a很大,那么将会造成很严重的性能问题,不过后来想想,可能是自己多虑了,于是查看go的文档,发现如下东西:

Passing arguments to ... parameters

If f is variadic with a final parameter p of type ...T, then within f the type of p is equivalent to type []T. If f is invoked with no actual arguments for p, the value passed to p is nil. Otherwise, the value passed is a new slice of type []T with a new underlying array whose successive elements are the actual arguments, which all must be assignable to T. The length and capacity of the slice is therefore the number of arguments bound to p and may differ for each call site.

Given the function and calls

func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")

within Greeting, who will have the value nil in the first call, and []string{"Joe", "Anna", "Eileen"} in the second.

If the final argument is assignable to a slice type []T, it may be passed unchanged as the value for a ...T parameter if the argument is followed by .... In this case no new slice is created.

Given the slice s and call

s := []string{"James", "Jasmine"}
Greeting("goodbye:", s...)

within Greeting, who will have the same value as s with the same underlying array.

也就是说,如果我们传入的是slice...这种形式的参数,go不会创建新的slice。写了一个简单的例子验证:

package main

import "fmt"

func t(args ...int) {
fmt.Printf("%p\n", args)
} func main() {
a := []int{1,2,3}
b := a[1:] t(a...)
t(b...) fmt.Printf("%p\n", a)
fmt.Printf("%p\n", b)
} //output
0x1052e120
0x1052e124
0x1052e120
0x1052e124

可以看到,可变参数args的地址跟实际外部slice的地址一样,用的同一个slice。

golang函数可变参数传递性能问题的更多相关文章

  1. ARTS-S golang函数作为参数传递

    函数作为参数传递在单元测试的时候非常有用,看下面的例子. package main import "fmt" func output(f func(string, string, ...

  2. Python学习笔记7-把函数当参数传递、指定可变参数

    把函数当参数传递 # 函数参数传递 # 面向对象编程就是把对象传来传去 # 面向函数编程就是把函数传来传去 def mytest(num): return num * 2 # # 不光可以传递变量,还 ...

  3. Python中函数的参数传递与可变长参数

    转自旭东的博客原文 Python中函数的参数传递与可变长参数 Python中传递参数有以下几种类型: (1)像C++一样的默认缺省函数 (2)根据参数名传参数 (3)可变长度参数 示例如下: (1)默 ...

  4. GO开发[四]:golang函数

    函数 1.声明语法:func 函数名 (参数列表) [(返回值列表)] {} 2.golang函数特点: a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个 ...

  5. 了解golang的可变参数(... parameters),这一篇就够了

    在实际开发中,总有一些函数的参数个数是在编码过程中无法确定的,比如我们最常用的fmt.Printf和fmt.Println: fmt.Printf("一共有%v行%v列\n", r ...

  6. golang函数学习笔记

    golang函数特点: a.不支持重载,一个包不能有两个名字一样的函数 b.函数是一等公民,函数也是一种类型,一个函数可以赋值给变量 c.匿名函数 d.多返回值   例子1 func add(a, b ...

  7. PHP函数可变参数列表的具体实现方法介绍

    PHP函数可变参数列表可以通过_get_args().func_num_args().func_get_arg()这三个函数来实现.我们下面就对此做了详细的介绍. AD:2014WOT全球软件技术峰会 ...

  8. python:函数的参数传递方法演示

    """ 函数的参数传递方法演示 """ #1.位置传参 def normal(a, b, c): print("1.位置传参:&q ...

  9. Golang函数-匿名函数与闭包函数

    Golang函数-匿名函数与闭包函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

随机推荐

  1. Python作业之工资管理

    作业之工资管理 工资管理实现要求: 工资管理系统 Alex 100000 Rain 80000 Egon 50000 Yuan 30000 -----以上是info.txt文件----- 实现效果: ...

  2. jquery post跨域请求数据

    原先一直以为要实现跨域请求只能用jsonp,只能支持GET请求,后来了解到使用POST请求也可以实现跨域,但是需要在服务器增加Access-Control-Allow-Origin和Access-Co ...

  3. 算法工程师:双非渣硕是如何获得百度、京东双SP

    本人本科硕士皆双非,和牛客大佬们没得比,目前拿到的还可以的offer就是百度SP和京东SP,都是做的推荐算法,其他的不说了. 先说一下个人经历吧,学校比较水,实验室没有项目,实习经历:腾讯实习+滴滴实 ...

  4. linux常用命令随记

    常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir 创建目录 -p 创建目录,若无父目录,则创建p(paren ...

  5. 8.1 使用Python操作SQLite数据库

    SQLite是内嵌在Python中的轻量级.基于磁盘文件袋额数据库管理系统,不需要安装和配置服务,支持使用SQL语句来访问数据库.该数据库使用C语言开发,支持大多数SQL91标准,支持原子的.一致的. ...

  6. redis的数据持久化方案

    Redis的持久化方案有两种 1.Rdb方式:快照形式,定期将内存中的数据持久化到硬盘.是Redis默认的数据持久化的形式. Rdb:缺点是:数据还没有更新到磁盘上,突然断电,造成数据的不完整性. 在 ...

  7. Matlab 编译EXE

    环境:vs2013  matlab2015b 一.生成独立可执行的程序(exe文件)步骤1.设置编译器.在matlab命令行输入mbuild –setup以及mex –setup,选择安装的c编译器. ...

  8. 纯CSS菜单样式,及其Shadow DOM,Json接口 实现

    先声明,要看懂这篇博客要求你具备少量基础CSS知识, 当然如果你只是要用的话就随便了,不用了解任何知识 完整项目github链接:https://github.com/git-Code-Shelf/M ...

  9. ThreadLocal深入剖析

    JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序,Threa ...

  10. An internal error occurred during: "Retrieving archetypes:". GC overhead limit exceeded

    An internal error occurred during: "Retrieving archetypes:".GC overhead limit exceeded 异常, ...