string数据结构

目录

一、string数据结构

二、切片和字符串转换

1. byte切片转string

2. string转byte切片

3. byte切片转换成string一定会拷贝内存吗?

4. string和byte切片适用场景

字符串拼接


一、string数据结构

type stringStruct struct {
    str unsafe.Pointer
    len int
}

str:字符串的首地址;
len:字符串的长度;


二、切片和字符串转换

1. byte切片转string

需要一次内存拷贝,转换过程:

1)【申请空间】:跟据切片的长度申请内存空间,假设内存地址为p,切片长度为len(b);

2)【构建string】:string.str = p;string.len = len;

3)【拷贝数据】:切片中数据拷贝到新申请的内存空间;

2. string转byte切片

也需要一次内存拷贝,其过程如下:

1)【申请内存】:申请切片内存空间;

2)【数据拷贝】:将string拷贝到切片;

3. byte切片转换成string一定会拷贝内存吗?

只是临时需要字符串的场景下,byte切片转换成string时并不会拷贝内存,而是直接返回一个string:

1)使用m[string(b)]来查找map(map是string为key,临时把切片b转成string);

2)字符串拼接,如”<” + “string(b)” + “>”;

3)字符串比较:string(b) == “foo”

4. string和byte切片适用场景

string 擅长的场景:

1)需要字符串比较的场景;

2)不需要nil字符串的场景;

byte切片擅长的场景:

1)修改字符串的场景;
2)函数返回值,需要用nil表示含义的场景;
3)需要切片操作的场景;


三、字符串拼接

【申请内存】第一次遍历获取总的字符串长度,据此申请内存;

【数据拷贝】第二次遍历会把字符串逐个拷贝过去;

func concatstrings(a []string) string { // 字符串拼接
    length := 0        // 拼接后总的字符串长度
    for _, str := range a {
        length += length(str)
    }
    s, b := rawstring(length) // 生成指定大小的字符串,返回一个string和切片,二者共享内存空间
    for _, str := range a {
        copy(b, str)    // string无法修改,只能通过切片修改
        b = b[len(str):]
    }
    return s
}

func rawstring(size int) (s string, b []byte) { // 生成一个新的string,返回的string和切片共享相同的空间
    p := mallocgc(uintptr(size), nil, false)
    stringStructOf(&s).str = p
    stringStructOf(&s).len = size
    *(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
    return
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值