golang中string slice array转换 byte

2020-08-28  本文已影响0人  无拘无束的猪

unsafe

1.Pointer 可以指向任意类型,实际上它类似于 C 语言里的 void*
2.pointer 不能直接进行数学运算,但可以把它转换成 uintptr,对 uintptr 类型进行数学运算,再转换成 pointer 类型。
注意:uintptr 并没有指针的语义,意思就是 uintptr 所指向的对象会被 gc 无情地回收。而 unsafe.Pointer 有指针语义,可以保护它所指向的对象在“有用”的时候不会被垃圾回收。

go/src/cmd/compile/internal/gc/unsafe.go 路径下,可以看到编译期间 Go 对 unsafe 包中函数的处理。

type Programmer struct {
    name string
    age int
    language string
}
func main() {
    p := Programmer{"stefno", 18, "go"}
    fmt.Println(p)
    lang := (*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&p)) + unsafe.Sizeof(int(0)) + unsafe.Sizeof(string(""))))
    *lang = "Golang"
    fmt.Println(p)
}
//通过 unsafe.Sizeof() 函数可以获取成员大小,进而计算出成员的地址,直接修改内存。

string和数字

int, err := strconv.Atoi(string) //转换成int
int64, err := strconv.ParseInt(string, 10, 64)//转成int64,也可以是0,8,16,32,64
string := strconv.Itoa(int)//int转成string
string := strconv.FormatInt(int64,10)//转成string

byte数组转string

string([...]byte)

string和slice

githubissues
src/reflect/value.go
反射有时候会被gc

type StringHeader struct {
    Data uintptr
    Len  int
}
type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}
func bytes2string(b []byte) (string){
    //pbytes:=(*reflect.SliceHeader)(unsafe.Pointer(&b))
    //pstring:=(*reflect.StringHeader)(unsafe.Pointer(&s))
    //pstring.Data = pbytes.Data
    //pstring.Len = pbytes.Len

    sliceHead:=(*reflect.SliceHeader)(unsafe.Pointer(&b))
    strHead:=reflect.StringHeader{
        sliceHead.Data,
        sliceHead.Len,
    }
        //runtime.KeepAlive(&bytes) // this line is essential.
    return *(*string)(unsafe.Pointer(&strHead))
}
func string2bytes(s string) ([]byte){
    //pbytes:=(*reflect.SliceHeader)(unsafe.Pointer(&b))
    //pstring:=(*reflect.StringHeader)(unsafe.Pointer(&s))
    //pbytes.Data = pstring.Data
    //pbytes.Len = pstring.Len
    //pbytes.Cap = pstring.Len

    stringHead:=(*reflect.StringHeader)(unsafe.Pointer(&s))
    sh:=reflect.SliceHeader{
        stringHead.Data,
        stringHead.Len,
        stringHead.Len,
    }

    return *(*[]byte)(unsafe.Pointer(&sh))
}

func string2bytes(s string) []byte {
    return *(*[]byte)(unsafe.Pointer(&s))
}
func bytes2string(b []byte) string{
    return *(*string)(unsafe.Pointer(&b))
}//more efficient way

slice和数组

slice底层就是数组

参考:
1.unsafe.Pointer使用

上一篇 下一篇

猜你喜欢

热点阅读