✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
下面分别针对 Go 的变量类型,验证是否是值传递,以及函数内对形参的修改是否会修改原内容数据:
25. map 类型
形参和实际参数内存地址不一样,证明是值传递。
go
package main
import "fmt"
func main() {
m := make(map[string]int)
m["age"] = 8
fmt.Printf("原始map的内存地址是:%p", &m)
modifyMap(m)
fmt.Printf("改动后的值是: %v", m)
}
func modifyMap(m map[string]int) {
fmt.Printf("函数里接收到map的内存地址是:%p", &m)
m["age"] = 9
}
原始map的内存地址是:0xc00000e028
函数里接收到map的内存地址是:0xc00000e038
改动后的值是: map[age:9]
通过 make 函数创建的 map 变量本质是一个 hmap 类型的指针 *hmap,所以函数内对形参的修改,会修改原内容数据。
go
//src/runtime/map.go
func makemap(t *maptype, hint int, h *hmap) *hmap {
mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size)
if overflow || mem > maxAlloc {
hint = 0
}
// initialize Hmap
if h == nil {
h = new(hmap)
}
h.hash0 = fastrand()
}
26. channel 类型
形参和实际参数内存地址不一样,证明是值传递。
go
package main
import (
"fmt"
"time"
)
func main() {
p := make(chan bool)
fmt.Printf("原始chan的内存地址是:%p", &p)
go func(p chan bool) {
fmt.Printf("函数里接收到chan的内存地址是:%p", &p)
//模拟耗时
time.Sleep(2 * time.Second)
p <- true
}(p)
select {
case l := <-p:
fmt.Printf("接收到的值是: %v", l)
}
}
原始chan的内存地址是:0xc00000e028
函数里接收到chan的内存地址是:0xc00000e038
接收到的值是: true
通过 make 函数创建的 chan 变量本质是一个 hchan 类型的指针 *hchan,所以函数内对形参的修改,会修改原内容数据。
go
// src/runtime/chan.go
func makechan(t *chantype, size int) *hchan {
elem := t.elem
// compiler checks this but be safe.
if elem.size >= 1<<16 {
throw("makechan: invalid channel element type")
}
if hchanSize%maxAlign != 0 || elem.align > maxAlign {
throw("makechan: bad alignment")
}
mem, overflow := math.MulUintptr(elem.size, uintptr(size))
if overflow || mem > maxAlloc-hchanSize || size < 0 {
panic(plainError("makechan: size out of range"))
}
}
27. struct 类型
形参和实际参数内存地址不一样,证明是值传递。形参不是引用类型或者指针类型,所以函数内对形参的修改,不会修改原内容数据。
go
package main
import "fmt"
type Person struct {
Name string
Age int
}
func main() {
per := Person{
Name: "test",
Age: 8,
}
fmt.Printf("原始struct的内存地址是:%p", &per)
modifyStruct(per)
fmt.Printf("改动后的值是: %v", per)
}
func modifyStruct(per Person) {
fmt.Printf("函数里接收到struct的内存地址是:%p", &per)
per.Age = 10
}
原始struct的内存地址是:0xc0000a6018
函数里接收到struct的内存地址是:0xc0000a6030
改动后的值是: {test 8}