我有一个像
这样的字符串的类型别名输入SpecialScopes字符串
我想使用strings.Join函数
加入这种类型的数组func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
return strings.Join(scopes, ",")
}
但是上面我得到了错误
cannot use scopes (type []SpecialScopes) as type []string in argument to strings.Join
cannot use strings.Join(scopes, ",") (type string) as type SpecialScopes in return argument
有没有办法让golang意识到SpecialScopes只是字符串的另一个名称并在其上执行连接功能? 如果不是最有效的方法是什么?我看到的一种方法是将数组中的所有元素转换为字符串,连接,然后将其强制转换回SpecialScopes并返回值
更新1: 我有一个工作实现,可以转换值。有什么建议可以更快地做到这一点吗?
func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
var s []string
for _, scope := range scopes {
s = append(s, string(scope))
}
return SpecialScopes(strings.Join(s, ","))
}
答案 0 :(得分:2)
以下是使用unsafe
包的解决方案:
func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
specialScopes := *(*[]string)((unsafe.Pointer(&scopes)))
s := strings.Join(specialScopes, ",")
return *(*SpecialScopes)((unsafe.Pointer(&s)))
}
答案 1 :(得分:2)
这主要是不使用不安全的最快方式。
func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
if len(scopes) == 0 {
return ""
}
var (
sep = []byte(", ")
// preallocate for len(sep) + assume at least 1 character
out = make([]byte, 0, (1+len(sep))*len(scopes))
)
for _, s := range scopes {
out = append(out, s...)
out = append(out, sep...)
}
return SpecialScopes(out[:len(out)-len(sep)])
}
基准代码:https://play.golang.org/p/DrB8nM-6ws
━➤ go test -benchmem -bench=. -v -benchtime=2s
testing: warning: no tests to run
BenchmarkUnsafe-8 30000000 109 ns/op 32 B/op 2 allocs/op
BenchmarkBuffer-8 20000000 255 ns/op 128 B/op 2 allocs/op
BenchmarkCopy-8 10000000 233 ns/op 112 B/op 3 allocs/op
BenchmarkConcat-8 30000000 112 ns/op 32 B/op 2 allocs/op
答案 2 :(得分:1)
如果你真的想快点,这是Go中更快的方式:
func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
var buffer bytes.Buffer
for ix, s := range scopes {
buffer.WriteString(string(s))
if ix < len(scopes)-1 {
buffer.WriteString(", ")
}
}
return SpecialScopes(buffer.String())
}
完整示例:https://play.golang.org/p/McWjh1yxHf
我知道它看起来并不像一个简单的.Join(),但它很容易阅读。