【Golang 面试题】每日 3 题(九)

✍个人博客: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}
相关推荐
Hammer_Hans21 小时前
DFT笔记33
笔记
雪碧聊技术1 天前
深入理解 Java GC:从“房间清洁工”到解决系统卡顿实战
java·开发语言
宵时待雨1 天前
C++笔记归纳17:哈希
数据结构·c++·笔记·算法·哈希算法
大鹏说大话1 天前
Java并发编程核心:线程安全、synchronized与volatile的深度剖析
java·开发语言
JAVA+C语言1 天前
Java IO 流
java·开发语言
酉鬼女又兒1 天前
零基础快速入门前端CSS Transform 与动画核心知识点及蓝桥杯 Web 应用开发考点解析(可用于备赛蓝桥杯Web应用开发)
开发语言·前端·css·职场和发展·蓝桥杯·html
山川行1 天前
Python快速闯关8:内置函数
java·开发语言·前端·笔记·python·学习·visual studio
charlie1145141911 天前
嵌入式C++教程实战之Linux下的单片机编程:从零搭建 STM32 开发工具链(2) —— HAL 库获取、启动文件坑位与目录搭建
linux·开发语言·c++·stm32·单片机·学习·嵌入式
Java基基1 天前
sdkman 一键切换 JDK 版本管理工具
java·开发语言·sdkman
春日见1 天前
GIT操作大全(个人开发与公司开发)
开发语言·驱动开发·git·matlab·docker·计算机外设·个人开发