Golang:对字符串

时间:2016-10-12 18:30:44

标签: go

我有一个像

这样的字符串的类型别名

输入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, ","))
}

3 个答案:

答案 0 :(得分:2)

以下是使用unsafe包的解决方案:

func MergeScopes(scopes ...SpecialScopes) SpecialScopes {
    specialScopes := *(*[]string)((unsafe.Pointer(&scopes)))
    s := strings.Join(specialScopes, ",")
    return *(*SpecialScopes)((unsafe.Pointer(&s)))
}

https://play.golang.org/p/-wsHY2eCdc

答案 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(),但它很容易阅读。