go语言学习十五 - StringBuilder

package main

import (
	"fmt"
	"strutils"
)

func main() {
	sb := strutils.NewStringBuilder("eg:")

	sb.Append(" hello").Append(" world.")
	sb.AppendFormat(" my name is %s and my age is %d.", "Tom", 22)

	fmt.Print(sb.ToString())
}

package strutils

import (
	"bytes"
	"fmt"
	"strings"
)

type StringBuilder struct {
	buf bytes.Buffer
}

func NewStringBuilder(s ...string) *StringBuilder {
	sb := StringBuilder{}
	sb.buf.WriteString(strings.Join(s, ""))
	return &sb
}

func (sb *StringBuilder) Append(s string) *StringBuilder {
	sb.buf.WriteString(s)
	return sb
}

func (sb *StringBuilder) AppendFormat(f string, s ...interface{}) *StringBuilder {
	sb.buf.WriteString(fmt.Sprintf(f, s...))
	return sb
}

func (sb *StringBuilder) String() string {
	return sb.ToString()
}

func (sb *StringBuilder) ToString() string {
	return sb.buf.String()
}
  • go语言的字符串处理能在字节层面能解决的问题就直接在字节层面解决。这样做性能更高。
  • 字符串和字节数组之间相互转换底层字节无需复制,转换效率 O(1) 与转换长度没有关系。
  • 明白没必要在内置库提供按照 rune 字符取位置的 substring 和 indexOf 函数的原因了。
package strutils

import (
	"strings"
	"unicode/utf8"
)

//实际工作中一般不会要求返回固定位置后的字符串,如果真有这种需求一般固定位置前的字符类型(纯Ascii还是多字节字符)是确定的。
func Substr(str string, s, e int) string {

	l, n := len(str), utf8.RuneCountInString(str)

	if s < 0 || s > n {
		return ""
	}

	if e < 0 || e > n || e < s {
		return str
	}

	if l == n { //pure ascii string
		return str[s:e]
	}
	//utf8 format
	return string([]rune(str)[s:e])
}

//实际需求中,一般是返回某个标识 字符串后的字符串,这种操作完全可以在 byte[] 级别完成,不必调用 utf8 方法
// go 没有提供 rune 层面的 substring(s string, s,e int) string  是有原因的 
func StrStart(str, s string) string {

	i := strings.Index(str,s)
	if i <0 {
		return str
	}
	
	return str[i:]
}

package main

import (
	"fmt"
)

func main() {
	
	s := "你好,世界.æ" //汉字:3byte; ascii:1byte; 英语音标字符:2byte
	fmt.Println(strings.Index(s,"好")) //3
	fmt.Println(strings.IndexRune(s,'好')) //3 
	//返回索引1 的 IndexXXX 函数 go 内置库没有提供,结合没有提供按照 rune 位置的 substring 考虑,这样的IndexXXX也是不需要的。

	for i, b := range []byte(s) {
		fmt.Printf("%d %d\n", i, b) //i=0~15 ; 3*4+2*1+1*2 = 16
	}

	fmt.Println("=============")

	n := len(s)
	for i:=0;i<n;i++ {
		fmt.Printf("%d %d\n", i, s[i]) //效果同上
	}

	for i, b := range []rune(s) {
		//按rune字符迭代
		fmt.Printf("%d %d %c,", i, b,b) //0 20320 你,1 22909 好,2 44 ,,3 19990 世,4 30028 界,5 46 .,6 230 æ
	}

}

转载于:https://www.cnblogs.com/scala/p/9598598.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值