golang初学者: string, [...]TYPE, []TYPE类型浅析 & golang 的内存管理

loop_0 · · 1093 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

# go string类型 ## string类型变量 ```c //go语言中的string类型像是c语言中的 struct string{ size_t len ; char const * data ; //指向[...]byte类型的数组 }; ``` ## string = 运算符赋值操作 ```go /* string类型 = 赋值运算符, 推测使用浅copy, string类型不提供修改索引的[...]byte类型数组的方法,并且go语言实现了gc垃圾回收机制,不需要关心内存释放的问题,所以单纯的赋值操作,没有必要进行深copy,使用浅copy可以提高性能,节省内存空间 */ ``` # go [...]TYPE array类型 ## [...]TYPE类型变量 ```c /** go 语言中array类型对传统c语言array的概念进行了重新定义,不再是c语言中的数组名代表数组首元素地址, 数组名不再 ≈ 指针. 数组名成为了真正的数组变量,代表了整个数组所有元素的数据, 同类型的数组变量之间可以互相赋值. */ //go语言中的数组像是c语言中的 struct arr_LEN{ TYPE data[LEN]; }; ``` # go []TYPE slice类型 ## []TYPE类型变量 ```c /** go语言slice类型,slice的本质以c语言表示 */ struct slice{ size_t len ; size_t cap ; TYPE *data ; }; ``` ## []TYPE类型 = 运算符赋值操作 ```go /** slice类型 = 赋值运算符的操作和string类型相同,使用浅copy的方式, 这也受益于gc机制的好处,浅copy可以达到c语言数组传址的效果, 弥补了go [...]TYPE array类型不能传址问题 */ /** 创建var arr = [4]int{1,2,3,4} slice.len = 4 slice.cap = 4 slice.data = &arr[0] */ slice1 = []int{1, 2, 3, 4} //浅拷贝输出结果相同 var slice2 = slice1 fmt.Println(slice1, len(slice1), cap(slice1)) fmt.Println(slice2, len(slice2), cap(slice2)) fmt.Printf("%p, %p\n", &slice1[0], &slice2[0]) ``` # go 的内存管理 ```go package main import "fmt" /** golang不允许程序员操作函数栈, 函数中定义的所有变量全部创建在gc机制维护的运行时堆中,哪怕是一个基本类型(如:uint8, bool)的变量, 其内存也分配在运行时堆中, 被gc机制管理释放 golang 比起"21世纪的c语言"这个比喻, 个人感觉"编译型的python"更贴切一点 */ func clearFuncStack() { var ( n1 = uint64(0) n2 = uint64(0) n3 = uint64(0) n4 = uint64(0) ) fmt.Println(n1, n2, n3, n4) } func retBaseTypePointer() *uint32 { var number = uint32(0xffffffff) return &number } func retArrPointer() *[4]int { var arr = [4]int{0x11, 0x12, 0x13, 0x14} return &arr } func retSlicePointer() *[]int { var slice = []int{0x1, 0x2, 0x3, 0x4} return &slice } func retStringPointer() *string { var text = string("hello, world") return &text } func main() { fmt.Println("hello, loop") var temp uint64 var uintptr *uint32 uintptr = retBaseTypePointer() clearFuncStack() fmt.Printf("&temp:%p,&uniptr:%p, uniptr:%p, *uniptr:%#v\n", &temp, &uintptr, uintptr, *uintptr) var arrptr *[4]int arrptr = retArrPointer() clearFuncStack() fmt.Printf("&temp:%p,&arrptr:%p, arrptr:%p, *arrptr:%#v\n", &temp, &arrptr, arrptr, *arrptr) var sliceptr *[]int sliceptr = retSlicePointer() clearFuncStack() fmt.Printf("&temp:%p,&sliceptr:%p, sliceptr:%p, *slliceptr:%#v\n", &temp, &sliceptr, sliceptr, *sliceptr) var strptr *string strptr = retStringPointer() clearFuncStack() fmt.Printf("&temp:%p,&strptr:%p, strptr:%p, *strptr:%#v\n", &temp, &strptr, strptr, *strptr) } ```

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1093 次点击  ∙  1 赞  
加入收藏 微博
2 回复  |  直到 2020-03-13 21:14:24
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传