当前位置: 首页 > news >正文

谷歌网站地图提交学做电商需要多少钱

谷歌网站地图提交,学做电商需要多少钱,香港的网站打不开,如何管理网站域名Go 官方的定义 本部分引用 Go 官方 FAQ 的 “When are function parameters passed by value?”,内容如下。 如同 C 系列的所有语言一样,Go 语言中的所有东西都是以值传递的。也就是说,一个函数总是得到一个被传递的东西的副本&#xff0c…

Go 官方的定义

本部分引用 Go 官方 FAQ 的 “When are function parameters passed by value?”,内容如下。

如同 C 系列的所有语言一样,Go 语言中的所有东西都是以值传递的。也就是说,一个函数总是得到一个被传递的东西的副本,就像有一个赋值语句将值赋给参数一样。

传值和传引用

什么是传值(值传递)

传值的意思是:函数传递的总是原来这个东西的一个副本,一副拷贝。其指的是在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 比如我们传递一个int类型的参数,传递的其实是这个参数的一个副本;传递一个指针类型的参数,其实传递的是这个该指针的一份拷贝,而不是这个指针指向的值。

对于int这类基础类型我们可以很好的理解,它们就是一个拷贝,但是指针呢?我们觉得可以通过它修改原来的值,怎么会是一个拷贝呢?下面我们看个例子。

test_demo.go

package mainimport ("fmt""testing"
)func modify(ip *int) {fmt.Printf("函数里接收到的指针的内存地址是:%p\n", &ip)*ip = 1
}func TestDemo(t *testing.T) {i := 10ip := &ifmt.Printf("原始指针的内存地址是:%p\n", &ip)modify(ip)fmt.Println("int值被修改了,新值为:", i)}

输出结果:

原始指针的内存地址是:0xc00000e038
函数里接收到的指针的内存地址是:0xc00000e040
int值被修改了,新值为: 1

什么是传引用(引用传递)

传引用,也叫做引用传递, 指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

在 Go 语言中,官方已经明确了没有传引用,也就是没有引用传递这一情况。

争议最大的 map 和 slice
这时候又有小伙伴疑惑了,你看 Go 语言中的 map 和 slice 类型,能直接修改,难道不是同个内存地址,不是引用了?

其实在 FAQ 中有一句提醒很重要:“map 和 slice 的行为类似于指针,它们是包含指向底层 map 或 slice 数据的指针的描述符”。

迷惑map

package mainimport ("fmt""testing"
)func modify(p map[string]int) {fmt.Printf("函数里接收到map的内存地址是:%p\n", &p)p["张三"] = 20
}func TestDemo(t *testing.T) {persons := make(map[string]int)persons["张三"] = 19mp := &personsfmt.Printf("原始map的内存地址是:%p\n", mp)modify(persons)fmt.Println("map值被修改了,新值为:", persons)
}

输出结果:

原始map的内存地址是:0xc000114028
函数里接收到map的内存地址是:0xc000114030

确实是值传递,那修改后的 map 的结果应该是什么。既然是值传递,那肯定就是 “这次一定!",对吗?

输出结果:

map值被修改了,新值为: map[张三:20]

原因:

指针类型可以修改,非指针类型不行,可以大胆的猜测,使用make函数创建的map是不是一个指针类型呢?看一下源代码:

// makemap implements a Go map creation make(map[k]v, hint)
// If the compiler has determined that the map or the first bucket
// can be created on the stack, h and/or bucket may be non-nil.
// If h != nil, the map can be created directly in h.
// If bucket != nil, bucket can be used as the first bucket.
func makemap(t *maptype, hint int64, h *hmap, bucket unsafe.Pointer) *hmap {//省略无关代码
}

通过查看src/runtime/hashmap.go源代码发现,注意其返回的是 *hmap类型,是一个指针。也就是 Go 语言通过对 map 类型的相关方法进行封装,达到了用户需要关注指针传递的作用。

现在看func modify(p map)这样的函数,其实就等于func modify(p *hmap),和前面什么是值传递里举的func modify(ip *int)的例子一样,可以参考分析。

这类情况我们称其为 “引用类型” ,但 “引用类型” 不等同于就是传引用,又或是引用传递了,还是有比较明确的区别的。

chan类型

chan类型本质上和map类型是一样的,这里不做过多的介绍,参考下源代码:

func makechan(t *chantype, size int64) *hchan {//省略无关代码
}

chan也是一个引用类型,和map相差无几,make返回的是一个*hchan

和map、chan都不一样的slice

slicemapchan都不太一样的,一样的是,它也是引用类型,它也可以在函数中修改对应的内容。

package mainimport ("fmt""testing"
)func modify(ages []int) {fmt.Printf("函数里接收到slice的内存地址是%p\n", ages)ages[0] = 1
}func TestDemo(t *testing.T) {ages := []int{6, 6, 6}fmt.Printf("原始slice的内存地址是%p\n", ages)modify(ages)fmt.Println(ages)
}

从结果来看,两者的内存地址一样,也成功的变更到了变量 ages 的值。这难道不是引用传递吗?
关注两个细节:

  • 没有用 & 来取地址。
  • 可以直接用 %p 来打印。

之所以可以同时做到上面这两件事,是因为标准库 fmt 针对在这一块做了优化:

func (p *pp) fmtPointer(value reflect.Value, verb rune) {var u uintptrswitch value.Kind() {case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:u = value.Pointer()default:p.badVerb(verb)return}//省略部分代码
}

通过源代码发现,对于chanmapslice等被当成指针处理,通过value.Pointer()获取对应的值的指针。

// If v's Kind is Slice, the returned pointer is to the first
// element of the slice. If the slice is nil the returned value
// is 0.  If the slice is empty but non-nil the return value is non-zero.
func (v Value) Pointer() uintptr {// TODO: deprecatek := v.kind()switch k {//省略无关代码case Slice:return (*SliceHeader)(v.ptr).Data}
}

很明显了,当是slice类型的时候,返回是slice这个结构体里,字段Data第一个元素的地址。

type SliceHeader struct {Data uintptrLen  intCap  int
}type slice struct {array unsafe.Pointerlen   intcap   int
}

在 Go 语言运行时,传递的也是相应 slice 类型的底层数组的指针,但需要注意,其使用的是指针的副本。严格意义是引用类型,依旧是值传递。slice是一种结构体+元素指针的混合类型,通过元素array(Data)的指针,可以达到修改slice里存储元素的目的。

总结

最终可以确认的是Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。

让最多人犯迷糊的就是 slicemapchan 等类型,都会认为是 “引用传递”,从而认为 Go 语言的 xxx 就是引用传递。正因为它们还引用类型(指针、map、slice、chan等这些),这样就可以修改原内容数据。

再记住,Go里只有传值(值传递)。

参考

群里又吵起来了,Go 是传值还是传引用?
Go语言参数传递是传值还是传引用

http://www.lbrq.cn/news/2465893.html

相关文章:

  • 公司两学一做网站seo高手培训
  • 百度云服务器做php网站菏泽资深seo报价
  • 怎样建设个人手机网站河北百度seo软件
  • 兰州网站建设哪家专业挖掘关键词工具
  • 黄岩地区做环评立项在哪个网站定制开发公司
  • 滁州做网站电话号码吉林seo管理平台
  • 无锡商业网站建设站长工具服务器查询
  • 南宁网站建设公司哪家好seo专业培训学费多少钱
  • wordpress带会员中心主题福州百度seo排名
  • 天津市工程建设项目报建网站推广app佣金平台正规
  • 深圳福田大型商城网站建设网站推广策划思路
  • 专业做数据的网站有哪些在线域名解析ip地址
  • 手机如何做车载mp3下载网站网络营销策略的制定
  • 东莞大型网站建设公司谷歌官方app下载
  • 西青做网站的公司江苏网页定制
  • 手机站网站建设西安seo外包公司
  • 沧州市网站建设电话黑帽seo培训网
  • quiz在哪个网站做seo优化服务商
  • 旅游网站前端模板关键词的作用
  • 天水做网站电话seo深圳培训班
  • 规划营销型网站结构社会新闻最新消息
  • 良精企业网站系统小广告多的网站
  • 怎么免费制作网站平台舆情危机公关公司
  • 行业网站cms长沙seo推广公司
  • 网站前台与后台建设的先后次序企业线上培训课程
  • 自己怎么做家政网站如何做网站推广优化
  • 做视频点播网站如何赚钱自助建站seo
  • 中小企业门户网站的建设方案河北百度seo关键词排名
  • 上海网站微信平台建设search搜索引擎
  • 地方网站不让做吗进一步优化
  • [NLP]UPF+RTL联合仿真的VCS命令及UPF-aware 波形工具的使用
  • 基于新型群智能优化算法的BP神经网络初始权值与偏置优化
  • Java环境配置之各类组件下载安装教程整理(jdk、idea、git、maven、mysql、redis)
  • 大模型Prompt优化工程
  • Shell的正则表达式
  • 如何使用 pdfMake 中文字体