package main /* #include <stdlib.h> */ import "C" import ( "unsafe" "fmt" ) type Slice struct { Data unsafe.Pointer //萬能指針類型 對應C語言中的void* len int //有效... ...
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 }