package main /* #include <stdlib.h> */ import "c" import ( "unsafe" "fmt" ) type slice struct { data unsafe.pointer //万能指针类型 对应c语言中的void* len int //有效的长度 cap int //有效的容量 } const tag = 8 /* func main() { //定义一个切片 //1、数据内存地址 2、len 有效数据长度 3、cap 可扩容的有效容量 24字节 var s []int //unsafe.sizeof 计算数据类型在内存中占的字节大小 fmt.println(unsafe.sizeof(s)) } */ /* func main(){ var i interface{} i=10//只支持== != //类型断言 是基于接口类型数据的转换 //value,ok:=i.(int) //if ok{ // fmt.println("整型数据:",value) // fmt.printf("%t\n",value) //} //反射获取接口的数据类型 //t:=reflect.typeof(i) //fmt.println(t) //反射获取接口类型数据的值 v:=reflect.valueof(i) fmt.println(v) i1:=10 i2:=20 if reflect.typeof(i1)==reflect.typeof(i2){ v1:=reflect.valueof(i1) v2:=reflect.valueof(i2) 结果=v1+v2 } } */ //create(长度 容量 数据) func (s *slice) create(l int, c int, data ...int) { //如果数据为空返回 if len(data) == 0 { return } //长度小于0 容量小于0 长度大于容量 数据大于长度 if l < 0 || c < 0 || l > c || len(data) > l { return } //ulonglong unsigned long long 无符号的长长整型 //通过c语言代码开辟空间 存储数据 //如果堆空间开辟失败 返回值为null 相当于nil 内存地址编号为0的空间 s.data = c.malloc(c.ulonglong(c) * 8) s.len = l s.cap = c //转成可以计算的指针类型 p := uintptr(s.data) for _, v := range data { //数据存储 *(*int)(unsafe.pointer(p)) = v //指针偏移 p += tag //p+=unsafe.sizeof(1) } } //print 打印切片 func (s *slice) print() { if s == nil { return } //将万能指针转成可以计算的指针 p := uintptr(s.data) for i := 0; i < s.len; i++ { //获取内存中的数据 fmt.print(*(*int)(unsafe.pointer(p)), " ") p += tag } } //切片追加 func (s *slice) append(data ...int) { if s == nil { return } if len(data) == 0 { return } //如果添加的数据超出了容量 if s.len+len(data) > s.cap { //扩充容量 //c.realloc(指针,字节大小), go 语言 2 倍扩容。 s.data = c.realloc(s.data, c.ulonglong(s.cap)*2*8) //改变容量的值 s.cap = s.cap * 2 } p := uintptr(s.data) for i := 0; i < s.len; i++ { //指针偏移 p += tag } //添加数据 for _, v := range data { *(*int)(unsafe.pointer(p)) = v p += tag } //更新有效数据(长度) s.len = s.len + len(data) } //获取元素 getdata(下标) 返回值为int 元素 func (s *slice) getddata(index int) int { if s == nil || s.data == nil { return 0 } if index < 0 || index > s.len-1 { return 0 } p := uintptr(s.data) for i := 0; i < index; i++ { p += tag } return *(*int)(unsafe.pointer(p)) } //查找元素 search(元素)返回值为int 下标 func (s *slice) search(data int) int { if s == nil || s.data == nil { return -1 } p := uintptr(s.data) for i := 0; i < s.len; i++ { //查找数据 返回第一次元素出现的位置 if *(*int)(unsafe.pointer(p)) == data { return i } //指针偏移 p += tag } return -1 } //删除元素 delete(下标) func (s *slice) delete(index int) { if s == nil || s.data == nil { return } if index < 0 || index > s.len-1 { return } //将指针指向需要删除的下标位置 p := uintptr(s.data) for i := 0; i < index; i++ { p += tag } //用下一个指针对应的值为当前指针对应的值进行赋值 temp := p for i := index; i < s.len; i++ { temp += tag *(*int)(unsafe.pointer(p)) = *(*int)(unsafe.pointer(temp)) p += tag } s.len-- } //插入元素 insert(下标 元素) func (s *slice) insert(index int, data int) { if s == nil || s.data == nil { return } if index < 0 || index > s.len-1 { return } //如果插入数据是最后一个 //if index == s.len-1 { // p := uintptr(s.data) // // //for i := 0; i < s.len; i++ { // // p += tag // //} // p += tag * uintptr(s.len-1) // *(*int)(unsafe.pointer(p)) = data // s.len++ // return //} //调用追加方法 if index == s.len-1 { s.append(data) return } //获取插入数据的位置 p := uintptr(s.data) for i := 0; i < index; i++ { p += tag } //获取末尾的指针位置 temp := uintptr(s.data) temp += tag * uintptr(s.len) //将后面数据依次向后移动 for i := s.len; i > index; i-- { //用前一个数据为当前数据赋值 *(*int)(unsafe.pointer(temp)) = *(*int)(unsafe.pointer(temp - tag)) temp -= tag } //修改插入下标的数据 *(*int)(unsafe.pointer(p)) = data s.len++ } //销毁切片 func (s *slice) destroy() { //调用c语言 适释放堆空间 c.free(s.data) s.data = nil s.len = 0 s.cap = 0 s = nil }