1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
// slicebytetostring converts a byte slice to a string.
// It is inserted by the compiler into generated code.
// ptr is a pointer to the first element of the slice;
// n is the length of the slice.
// Buf is a fixed-size buffer for the result,
// it is not nil if the result does not escape.
func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
// 没有需要转换的
if n == 0 {
// Turns out to be a relatively common case.
// Consider that you want to parse out data between parens in "foo()bar",
// you find the indices and convert the subslice to string.
return ""
}
if raceenabled {
racereadrangepc(unsafe.Pointer(ptr),
uintptr(n),
getcallerpc(),
abi.FuncPCABIInternal(slicebytetostring))
}
if msanenabled {
msanread(unsafe.Pointer(ptr), uintptr(n))
}
if asanenabled {
asanread(unsafe.Pointer(ptr), uintptr(n))
}
// 当[]byte 只有一个字符时
if n == 1 {
// staticuint64s是一个[256]uint64的数组,也就是ASCII的数组数组
// 这里可以看出并不是用的同一个底层数组。
p := unsafe.Pointer(&staticuint64s[*ptr])
if goarch.BigEndian { // 某些平台需要字节对齐
p = add(p, 7)
}
stringStructOf(&str).str = p // 赋值给字符串的str
stringStructOf(&str).len = 1 // 赋值给字符串的len
return
}
var p unsafe.Pointer
if buf != nil && n <= len(buf) { // 当长度在32范围内时
p = unsafe.Pointer(buf) // 直接使用buf的容量当做地址
} else {
p = mallocgc(uintptr(n), nil, false) // 申请n大小的内存地址备用
}
stringStructOf(&str).str = p
stringStructOf(&str).len = n
memmove(p, unsafe.Pointer(ptr), uintptr(n)) // 将ptr地址长度为n字节的内容移动到p中
return
}
|