写在前面
由于前面用惯了Java,突然来到Golang,发现,诶,StringBuilder,Buffer去哪儿了,怎么使用呢。
于是乎,借着Java的使用习惯,实现了如下的简易版StringBuilder。
实现
定义好一个struct:
// StrBuilder the string builder
type StrBuilder struct {
buf strings.Builder
len int64
}
然后实现其几个基本的方法:
追加,长度,类型转换:
其中使用到了golang的一个反射机制,判断追加的对象类型。
// StrAppend 大量字符串的拼接:like the StringBuilder(Java).append(Object).
func (sb *StrBuilder) StrAppend(t any) *StrBuilder {
type_t := reflect.TypeOf(t)
value_t := reflect.ValueOf(t)
if type_t.Kind() == reflect.String {
sb.buf.WriteString(value_t.String())
} else if type_t.Kind() == reflect.Int64 {
sb.buf.WriteString(strconv.FormatInt(value_t.Int(), 10))
} else {
panic(TypeError)
}
return sb
}
func (sb *StrBuilder) ToString() string {
return sb.buf.String()
}
func (sb *StrBuilder) Len() int64 {
sb.len = int64(sb.buf.Len())
return sb.len
}
类似new对象:
// StrBuilder the string builder
func NewStrBuilder(t ...any) *StrBuilder {
var sb = new(StrBuilder)
for _, v := range t {
sb.StrAppend(v)
}
return sb
}
测试
测试,同样的处理10万条字符串拼接,所用耗时:
package test
import (
"testing"
"time"
"gogs.buffalo-robot.com/services/scheduleTreatment/internal/utils"
)
func TestStrBuilder(t *testing.T) {
var sb = utils.NewStrBuilder("cheng jiang")
sb.StrAppend(", i make the string append easily.")
t.Log(sb.ToString())
sb.StrAppend(" my age is: ").StrAppend(int64(100000000))
t.Log(sb.ToString(), sb.Len())
// 测试一下分别直接拼接和使用builder的性能。
var sb1 = utils.NewStrBuilder("")
start1 := time.Now()
for i := 0; i < 100000; i++ {
sb1.StrAppend("hhh")
}
end1 := time.Now()
start2 := time.Now()
var str = ""
for i := 0; i < 100000; i++ {
str += "hhh"
}
end2 := time.Now()
t.Log("builder: ", end1.Sub(start1), ", string: ", end2.Sub(start2))
// the output:
// builder: 1.0368ms , string: 1.2644461s
}
out put:
可以看到,直接从1s到了1ms,少了三个数量级。非常的阔以。
到此实现和测试结束。