在Go中,字符串是一种基本类型,这意味着它是只读的,对它的每次操作都会创建一个新字符串。

如果我想多次连接字符串而不知道结果字符串的长度,最好的方法是什么?

最天真的做法是:

var s string
for i := 0; i < 1000; i++ {
    s += getShortStringFromSomewhere()
}
return s

但这似乎不是很有效。


当前回答

strings. join()来自"strings"包

如果你有一个类型不匹配(比如如果你试图连接一个int和一个字符串),你做RANDOMTYPE(你想改变的东西)

EX:

package main

import (
    "fmt"
    "strings"
)

var intEX = 0
var stringEX = "hello all you "
var stringEX2 = "people in here"


func main() {
    s := []string{stringEX, stringEX2}
    fmt.Println(strings.Join(s, ""))
}

输出:

hello all you people in here

其他回答

如果你有一个字符串切片,你想要有效地转换成一个字符串,那么你可以使用这种方法。否则,看看其他答案。

在strings包中有一个名为Join的库函数: http://golang.org/pkg/strings/#Join

看看Join的代码,可以看到Kinopiko写的类似于Append函数的方法:https://golang.org/src/strings/strings.go#L420

用法:

import (
    "fmt";
    "strings";
)

func main() {
    s := []string{"this", "is", "a", "joined", "string\n"};
    fmt.Printf(strings.Join(s, " "));
}

$ ./test.bin
this is a joined string

我使用以下方法:-

package main

import (
    "fmt"
    "strings"
)

func main (){
    concatenation:= strings.Join([]string{"a","b","c"},"") //where second parameter is a separator. 
    fmt.Println(concatenation) //abc
}

简单易消化的解决方案。详情请见评论。 Copy覆盖slice的元素。我们对单个元素进行切片,然后覆盖它。

package main

import (
    "fmt"
)

var N int = 100000

func main() {
    slice1 := make([]rune, N, N)
    //Efficient with fast performance, Need pre-allocated memory
    //We can add a check if we reached the limit then increase capacity
    //using append, but would be fined for data copying to new array. Also append happens after the length of current slice.
    for i := 0; i < N; i++ {
        copy(slice1[i:i+1], []rune{'N'})
    }
    fmt.Println(slice1)

    //Simple but fast solution, Every time the slice capacity is reached we get a fine of effort that goes
    //in copying data to new array
    slice2 := []rune{}
    for i := 0; i <= N; i++ {
        slice2 = append(slice2, 'N')
    }
    fmt.Println(slice2)

}

您可以创建一个大的字节片,并使用字符串片将短字符串的字节复制到其中。在“Effective Go”中给出了一个函数:

func Append(slice, data[]byte) []byte {
    l := len(slice);
    if l + len(data) > cap(slice) { // reallocate
        // Allocate double what's needed, for future growth.
        newSlice := make([]byte, (l+len(data))*2);
        // Copy data (could use bytes.Copy()).
        for i, c := range slice {
            newSlice[i] = c
        }
        slice = newSlice;
    }
    slice = slice[0:l+len(data)];
    for i, c := range data {
        slice[l+i] = c
    }
    return slice;
}

然后,当操作完成时,在大字节片上使用string()将其再次转换为字符串。

goutils。JoinBetween

 func JoinBetween(in []string, separator string, startIndex, endIndex int) string {
    if in == nil {
        return ""
    }

    noOfItems := endIndex - startIndex

    if noOfItems <= 0 {
        return EMPTY
    }

    var builder strings.Builder

    for i := startIndex; i < endIndex; i++ {
        if i > startIndex {
            builder.WriteString(separator)
        }
        builder.WriteString(in[i])
    }
    return builder.String()
}