狗日的slice

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

首先推荐一下雨痕大神的新书:《Golang源码剖析(第五版)》

进入正题。Golang和其它语言不通的是,他增加了一个slice,这不同于传统的数组,但是我们使用它又要按照数组的用法来,容易混淆。

先说一下我理解的传统数组,数组的名称就是数组在内存里面的首地址,访问每个子元素就是首地址加子元素长度访问。所以这应该是一个引用对象类型。

而Golang的slice,引用一下雨痕大神的文章说明:

runtime.h

struct Slice
{
	byte* array;
	uintgo len;
	uintgo cap;
}

slice底层是通过struct实现的,所以传递的时候是值拷贝传递,但是,slice的内容是通过数组指针实现的。就会发生这种现象:***通过值传递,lencap都不会变,所以使用的时候不会感觉到内容有变化,但是实际上byte数组是发生变化的。

上代码:

package main

import "fmt"

func main() {
	testMap := make(map[int64]int64)
	fmt.Println(testMap)
	FuckMap(testMap)
	fmt.Println(testMap)
	FuckMap2(testMap)
	fmt.Println(testMap)

	testSlice := []int64{}
	fmt.Println(testSlice)
	FuckSlice(testSlice)
	fmt.Println(testSlice)
	
	FuckSlice2(&testSlice)
	fmt.Println(testSlice)
}

func FuckMap(t map[int64]int64) map[int64]int64 {
	t[1] = 1
	return t
}

func FuckMap2(t map[int64]int64) map[int64]int64 {
	t[1] = 2
	return t
}

func FuckSlice(a []int64) []int64 {
	a = append(a, 1)
	return a
}

func FuckSlice2(a *[]int64) *[]int64 {
	*a = append(*a, 1)
	return a
}

直接看后半部分。FuckSlice函数对于slice的修改是不起作用的,因为slice是按值传递的;然后我们强行改成按引用传递,就是传递slice的地址作为参数,这时的修改就是起作用的。所以,对于修改slice的操作要注意,有可能会修改失败。



原文链接:狗日的slice,转载请注明来源!


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

本文来自:Cyeam

感谢作者:Bryce

查看原文:狗日的slice

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

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