github.com/rolandhe/saber@v0.0.4/utils/strutil/unistring.go (about)

     1  // Package strutils, string tool
     2  //
     3  // Copyright 2023 The saber Authors. All rights reserved.
     4  //
     5  
     6  // Package strutil string工具集合,提供:
     7  //
     8  //  1. 获取string 中unicode 字符的个数
     9  //
    10  //  2. 快速从string中获取其 []byte, 之所以快,是避免了内存分配和复制
    11  //
    12  //  3. 快速把 []byte 转换成 string,之所以快,是避免了内存分配和复制
    13  package strutil
    14  
    15  import (
    16  	"reflect"
    17  	"unicode/utf8"
    18  	"unsafe"
    19  )
    20  
    21  // GetRuneLenOfString 返回一个字符串的unicode字符个数
    22  func GetRuneLenOfString(s string) int {
    23  	return utf8.RuneCountInString(s)
    24  }
    25  
    26  // DetachBytesString 直接获取string底层的utf8字节数组并转换成只读的[]byte,
    27  // 注意, 返回的[]byte只能被读取,不能被修改
    28  // 使用[]byte(s)会造成底层Slice复制字符串的内容,造成内存的分配,效率不好,在只读场景中可以使用本函数来提高效率
    29  func DetachBytesString(s string) []byte {
    30  	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
    31  	sl := &reflect.SliceHeader{Data: sh.Data, Len: sh.Len, Cap: sh.Len}
    32  
    33  	return *(*[]byte)(unsafe.Pointer(sl))
    34  }
    35  
    36  // AttachBytesString 生成直接挂接[]byte的字符串,与DetachBytesString类似,他会提高效率,
    37  // 使用string([]byte)底层会分配内存,造成效率不高,使用本方法会避免分配内存,
    38  // 在打印输出json输出的内容时会非常有效
    39  func AttachBytesString(b []byte) string {
    40  	sl := (*reflect.SliceHeader)(unsafe.Pointer(&b))
    41  	sh := &reflect.StringHeader{Data: sl.Data, Len: sl.Len}
    42  
    43  	return *(*string)(unsafe.Pointer(sh))
    44  }