Go 在不重新分配新切片的情况下将项附加到可变函数包装器
好的,我需要一个fmt.Printf()的小包装,以便于调试: 1/“调用fmt.Fprintln时参数太多”: 2/“接口类型中不允许使用名称列表”: 3/工作正常,但感觉不对劲:Go 在不重新分配新切片的情况下将项附加到可变函数包装器,go,variadic-functions,Go,Variadic Functions,好的,我需要一个fmt.Printf()的小包装,以便于调试: 1/“调用fmt.Fprintln时参数太多”: 2/“接口类型中不允许使用名称列表”: 3/工作正常,但感觉不对劲: func Debug (a ... interface{}) { if debug { sl := make ([]interface{}, len(a) + 2) sl[0] = prefix sl[1] = sep for i, v :=
func Debug (a ... interface{}) {
if debug {
sl := make ([]interface{}, len(a) + 2)
sl[0] = prefix
sl[1] = sep
for i, v := range a {
sl[2+i] = v
}
fmt.Fprintln(out, sl...)
}
}
有没有办法避免分配额外内存?没有办法避免分配额外内存 最短、最有效的Go代码似乎是:
func Debug (a ...interface{}) {
if debug {
b := make([]interface{}, 0, 2+len(a))
b = append(b, prefix, sep)
b = append(b, a...)
fmt.Fprintln(out, b...)
}
}
次要说明:在第二个示例中,缺少一个{}:
fmt.Fprintln(out, []interface{}{prefix, sep}...)
我会写:
func Debug(a ...interface{}) {
if debug {
aa := make([]interface{}, 0, 2+len(a))
aa = append(append(aa, prefix, sep), a...)
fmt.Fprintln(out, aa...)
}
}
分配只在调试模式下进行,那么为什么debug
函数分配的数量很大
Gofmt
包因其通用性而昂贵;它使用反射、分配和I/O。为什么Debug
函数分配相对重要
您考虑过使用吗?我只需要打印两张:
func Debug(a ...interface{}) {
if debug {
fmt.Fprint(out, prefix, sep)
fmt.Fprintln(out, a...)
}
}
如果您认为需要给Fprint打一个电话,您可以这样做
func Debug(a ...interface{}) {
if debug {
fmt.Fprint(out, prefix, sep, fmt.Sprintln(a...))
}
}
任何一种方法都比构建新切片更简单。可变参数可以用作切片,因此无需分配新切片:
func Debug(a ...interface{}) {
if debug {
a = append(a, 0)
copy(a[1:], a[0:])
a[0] = prefix + sep
fmt.Fprintln(out, a...)
}
}
有关工作示例,请参见。对于一行程序,您也可以使用
append
:
func调试(一个…接口{}){
如果调试{
Fprintln(out,append([]接口{}{prefix,sep},a..}…)
}
}
len(aa)最初应该是0。好的,谢谢,我来看看日志包,似乎很有趣。回答你的问题:这并不重要,真的。这更是一个普遍的问题。谢谢你们两位的append()不过,func并不知道这一点,并且想知道如何向slices@Atom添加元素,这是为什么?它正在向len(a)+2发展,因为aa:=make([]接口{},2+len(a))
,len(aa)=2+len(a)和cap(aa)=2+len a
。对于,aa:+make([]接口{},0,2+len a))
,len=0
和cap(aa)=2+len(a)
。append从len(aa)
开始追加。这似乎是最好的方式,不分配也不复制。
func Debug(a ...interface{}) {
if debug {
fmt.Fprint(out, prefix, sep, fmt.Sprintln(a...))
}
}
func Debug(a ...interface{}) {
if debug {
a = append(a, 0)
copy(a[1:], a[0:])
a[0] = prefix + sep
fmt.Fprintln(out, a...)
}
}