向可变参数函数包装器添加项目而不重新分配新的切片

huangapple go评论82阅读模式
英文:

Appending items to a variadic function wrapper without reallocating a new slice

问题

好的,以下是翻译的内容:

1/ "too many arguments in call to fmt.Fprintln" :

func Debug(a ...interface{}) {
    if debug {
        fmt.Fprintln(out, prefix, sep, a...)
    }
}

2/ "name list not allowed in interface type" :

func Debug(a ...interface{}) {
    if debug {
        fmt.Fprintln(out, []interface{}{prefix, sep, a...}...)
    }
}

3/ Works, but feels wrong :

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...)
    }
}

有没有避免额外内存分配的想法?

英文:

Ok I need a small wrapper of fmt.Printf() for debugging conveniance :

1/ "too many arguments in call to fmt.Fprintln" :

func Debug (a ... interface{}) {
    if debug {
	    fmt.Fprintln(out, prefix, sep, a...)
    }
}

2/ "name list not allowed in interface type" :

func Debug (a ... interface{}) {
    if debug {
	    fmt.Fprintln(out, []interface{prefix, sep, a...}...)
    }
}

3/ Works, but feels wrong :

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...)
    }
}

Any ideas to avoid allocating extra memory ?

答案1

得分: 9

你也可以使用append来实现一行代码:

func Debug (a ...interface{}) {
    if debug {
        fmt.Fprintln(out, append([]interface{}{prefix, sep}, a...)...)
    }
}
英文:

You can also use append for a one-liner:

func Debug (a ...interface{}) {
    if debug {
        fmt.Fprintln(out, append([]interface{}{prefix, sep}, a...)...)
    }
}

答案2

得分: 5

我只会做两个打印:

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...))
    }
}

无论哪种方式都比构建一个新的切片更简单。

英文:

I would just do two prints:

func Debug(a ...interface{}) {
    if debug {
        fmt.Fprint(out, prefix, sep)
        fmt.Fprintln(out, a...)
    }
}

If you believed you needed to make a single call to Fprint, you could do,

func Debug(a ...interface{}) {
    if debug {
        fmt.Fprint(out, prefix, sep, fmt.Sprintln(a...))
    }
}

Either way seems simpler that building a new slice.

答案3

得分: 4

我会写:

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函数的分配数量很重要?

Go的fmt包很昂贵,因为它很通用;它使用反射,分配内存,并进行I/O操作。为什么Debug函数的分配相对重要?

你考虑过使用Go的log吗?

英文:

I would write:

func Debug(a ...interface{}) {
	if debug {
		aa := make([]interface{}, 0, 2+len(a))
		aa = append(append(aa, prefix, sep), a...)
		fmt.Fprintln(out, aa...)
	}
}

The allocation is only made in debug mode, so why is the number of Debug function allocations significant?

The Go fmt package is expensive because of its generality; it uses reflection, it allocates, and it does I/O. Why are the Debug function allocations relatively significant?

Have you considered using the Go log package?

答案4

得分: 3

可变参数可以用作切片,因此不需要分配新的切片:

func Debug(a ...interface{}) {
    if debug {
        a = append(a, 0)
        copy(a[1:], a[0:])
        a[0] = prefix + sep
        fmt.Fprintln(out, a...)
    }
}

请参阅 http://play.golang.org/p/xXEO58BJoA 获取一个可运行的示例。

英文:

Variadic arguments can be used as slices, so no need to allocate a new one:

func Debug(a ...interface{}) {
    if debug {
        a = append(a, 0)
        copy(a[1:], a[0:])
        a[0] = prefix + sep
        fmt.Fprintln(out, a...)
    }
}

See http://play.golang.org/p/xXEO58BJoA for a working example

答案5

得分: 1

没有办法避免分配额外的内存。

最短且最高效的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}...)
英文:

There is no way to avoid allocating extra memory.

The shortest and most efficient Go code seems to be:

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...)
    }
}

Minor note: In your 2nd example, you are missing a {}:

fmt.Fprintln(out, []interface{}{prefix, sep}...)

huangapple
  • 本文由 发表于 2011年12月22日 22:42:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/8605446.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定