在Go语言中,可变参数的打包和解包可以通过`[]string{f(v)}…`来实现。

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

variadic pack and unpack in go lang: '[]string{f(v)}...'

问题

我在浏览 GitHub 时找到了这个函数:

func Accumulate(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, []string{f(v)}...)
    }
    return result
}

这个方法可以简化为以下形式吗?还是我漏掉了什么?

func Accumulate(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, f(v))
    }
    return result
}
英文:

I found this function while browsing github:

func Accumulate(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, []string{f(v)}...)
    }
    return result
}

Could this method be simplified to the following, or am I missing something:

func Accumulate(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, f(v))
    }
    return result
}

答案1

得分: 1

你提供的代码是正确的,易于理解的。我写了一个基准测试:

package p

import (
    "testing"
    "strings"
)

var s = []string{"hello", "world", "this", "new", "world"}

func BenchmarkAcc1(b *testing.B) {
    for n := 0; n < b.N; n++ {
        Accumulate(s, strings.ToUpper)
    }
}

func BenchmarkAcc2(b *testing.B) {
    for n := 0; n < b.N; n++ {
        Accumulate2(s, strings.ToUpper)
    }
}

以下是我得到的一些结果:

% go test -benchtime=10s -bench=.
testing: warning: no tests to run
PASS
BenchmarkAcc1    10000000    1510 ns/op
BenchmarkAcc2    10000000    1492 ns/op
ok    _/home/satran/test    33.064s

如你所见,实际上并没有性能提升,事实上你的版本效果更好。

以下是源代码:

package p

func Accumulate(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, []string{f(v)}...)
    }
    return result
}

func Accumulate2(s []string, f func(st string) string) (result []string) {
    for _, v := range s {
        result = append(result, f(v))
    }
    return result
}

希望对你有帮助!

英文:

The version you have written is correct and sane to understand. I wrote a benchmark:

package p

import (
    &quot;testing&quot;
    &quot;strings&quot;
)

var s = []string{&quot;hello&quot;, &quot;world&quot;, &quot;this&quot;, &quot;new&quot;, &quot;world&quot;}

func BenchmarkAcc1(b *testing.B) {
	for n := 0; n &lt; b.N; n++ {
		Accumulate(s, strings.ToUpper)
	}
}

func BenchmarkAcc2(b *testing.B) {
	for n := 0; n &lt; b.N; n++ {
		Accumulate2(s, strings.ToUpper)
	}
}

Here are a few results I got:

% go test -benchtime=10s -bench=.
testing: warning: no tests to run
PASS
BenchmarkAcc1	10000000	      1510 ns/op
BenchmarkAcc2	10000000	      1492 ns/op
ok  	_/home/satran/test	33.064s

As you can see there is no performance gain either, in fact your version works better.

Here is the source:

package p

func Accumulate(s []string, f func(st string) string) (result []string) {
	for _, v := range s {
		result = append(result, []string{f(v)}...)
	}
	return result
}

func Accumulate2(s []string, f func(st string) string) (result []string) {
	for _, v := range s {
		result = append(result, f(v))
	}
	return result
}

huangapple
  • 本文由 发表于 2015年3月1日 06:04:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/28787489.html
匿名

发表评论

匿名网友

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

确定