blob: 7f130af87ab44677c503aa90c37b88737da09727 [file] [log] [blame]
// Copyright 2016 ~ 2018 AlexStocks(https://github.com/AlexStocks).
// All rights reserved. Use of this source code is
// governed by Apache License 2.0.
// http://blog.csdn.net/siddontang/article/details/23541587
// reflect.StringHeader和reflect.SliceHeader的结构体只相差末尾一个字段(cap)
// vitess代码,一种很hack的做法,string和slice的转换只需要拷贝底层的指针,而不是内存拷贝。
package gxstrings
import (
"reflect"
"unsafe"
)
func String(b []byte) (s string) {
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
pstring.Data = pbytes.Data
pstring.Len = pbytes.Len
return
}
func Slice(s string) (b []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
return
}
// returns &s[0], which is not allowed in go
func StringPointer(s string) unsafe.Pointer {
p := (*reflect.StringHeader)(unsafe.Pointer(&s))
return unsafe.Pointer(p.Data)
}
// returns &b[0], which is not allowed in go
func BytePointer(b []byte) unsafe.Pointer {
p := (*reflect.SliceHeader)(unsafe.Pointer(&b))
return unsafe.Pointer(p.Data)
}
// var (
// typeOfBytes = reflect.TypeOf([]byte(nil))
// )
// func CheckByteArray1(v interface{}) bool {
// vv := reflect.ValueOf(v)
// switch vv.Kind() {
// case reflect.Slice:
// if vv.Type() == typeOfBytes {
// return true
// }
// }
//
// return false
// }
// func CheckByteArray2(v interface{}) bool {
// _, ok := v.([]byte)
// return ok
// }