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

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

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/UWz06
📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

下面分别针对 Go 的变量类型,验证是否是值传递,以及函数内对形参的修改是否会修改原内容数据:

22. int 类型

形参和实参内存地址不一样,证明是指传递;参数是值类型,所以函数内对形参的修改,不会修改原内容数据。

package main

import "fmt"

func main() {
        var i int64 = 1
        fmt.Printf("原始int内存地址是 %p", &i)
        modifyInt(i) // args就是实际参数
        fmt.Printf("改动后的值是: %v", i)
}

func modifyInt(i int64) { //这里定义的args就是形式参数
        fmt.Printf("函数里接收到int的内存地址是:%p", &i)
        i = 10
}
原始int内存地址是 0xc0000180b8
函数里接收到int的内存地址是:0xc0000180c0
改动后的值是: 1

23. 指针类型

形参和实际参数内存地址不一样,证明是值传递,由于形参和实参是指针,指向同一个变量。函数内对指针指向变量的修改,会修改原内容数据。

package main

import "fmt"

func main() {
    var args int64 = 1                  // int类型变量
    p := &args                          // 指针类型变量
    fmt.Printf("原始指针的内存地址是 %p", &p)   // 存放指针类型变量
    fmt.Printf("原始指针指向变量的内存地址 %p", p) // 存放int变量
    modifyPointer(p)                    // args就是实际参数
    fmt.Printf("改动后的值是: %v", *p)
}

func modifyPointer(p *int64) { //这里定义的args就是形式参数
    fmt.Printf("函数里接收到指针的内存地址是 %p ", &p)
    fmt.Printf("函数里接收到指针指向变量的内存地址 %p", p)
    *p = 10
}
原始指针的内存地址是 0xc000110018
原始指针指向变量的内存地址 0xc00010c008
函数里接收到指针的内存地址是 0xc000110028 
函数里接收到指针指向变量的内存地址 0xc00010c008
改动后的值是: 10

24. slice 类型

形参和实际参数内存地址一样,不代表是引用类型;下面进行详细说明 slice 还是值传递,传递的是指针。

package main

import "fmt"

func main() {
        var s = []int64{1, 2, 3}
        // &操作符打印出的地址是无效的,是fmt函数作了特殊处理
        fmt.Printf("直接对原始切片取地址%v ", &s)
        // 打印slice的内存地址是可以直接通过%p打印的,不用使用&取地址符转换
        fmt.Printf("原始切片的内存地址: %p ", s)
        fmt.Printf("原始切片第一个元素的内存地址: %p ", &s[0])
        modifySlice(s)
        fmt.Printf("改动后的值是: %v", s)
}

func modifySlice(s []int64) {
        // &操作符打印出的地址是无效的,是fmt函数作了特殊处理
        fmt.Printf("直接对函数里接收到切片取地址%v", &s)
        // 打印slice的内存地址是可以直接通过%p打印的,不用使用&取地址符转换
        fmt.Printf("函数里接收到切片的内存地址是 %p ", s)
        fmt.Printf("函数里接收到切片第一个元素的内存地址: %p ", &s[0])
        s[0] = 10
}
直接对原始切片取地址&[1 2 3] 
原始切片的内存地址: 0xc0000b8000 
原始切片第一个元素的内存地址: 0xc0000b8000 
直接对函数里接收到切片取地址&[1 2 3]
函数里接收到切片的内存地址是 0xc0000b8000 
函数里接收到切片第一个元素的内存地址: 0xc0000b8000 
改动后的值是: [10 2 3]

slice 是一个结构体,他的第一个元素是一个指针类型,这个指针指向的是底层数组的第一个元素。当参数是 slice 类型的时候,fmt.printf 通过 %p 打印的 slice 变量的地址其实就是内部存储数组元素的地址,所以打印出来形参和实参内存地址一样。

type slice struct {
    array unsafe.Pointer // 指针
    len   int
    cap   int
}

因为 slice 作为参数时本质是传递的指针,上面证明了指针也是值传递,所以参数为 slice 也是值传递,指针指向的是同一个变量,函数内对形参的修改,会修改原内容数据。

单纯的从 slice 这个结构体看,我们可以通过 modify 修改存储元素的内容,但是永远修改不了 len 和 cap,因为他们只是一个拷贝,如果要修改,那就要传递 &slice 作为参数才可以。


http://www.kler.cn/a/458233.html

相关文章:

  • springboot 整合 rabbitMQ (延迟队列)
  • swagger,showdoc,apifox,Mock 服务,dubbo,ZooKeeper和dubbo的关系
  • 赛博周刊·2024年度工具精选(图片资源类)
  • 通过Cephadm工具搭建Ceph分布式存储以及通过文件系统形式进行挂载的步骤
  • 2024年总结与展望
  • Three.js教程004:坐标辅助器与轨道控制器
  • 可视化逻辑表达式编辑器
  • 计算机毕业设计Spark+大模型股票推荐系统 股票预测系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
  • 服务器开发Go语言的算法与数据结构
  • 随身 WiFi 连接 X-Wrt 共享网络与 IPv6 中继配置
  • 深入解析 Tengine:高性能 Web 服务器与反向代理的企业级应用
  • 【每日学点鸿蒙知识】Webview加载内容、router返回问题、Webview定制错误页面、html格式字符串、Toggle高
  • 深入探索Django:常用实用方法指南
  • 2025:Massa重新定义去中心化的一年
  • Nginx实现反向代理
  • 做一个网页控制ROS2机器人导航并且查看相机图像
  • 【探花交友】SpringCache
  • 应用于CPO封装模块内的光纤互联方案
  • django --递归查询评论
  • 如何将项目打包成 Docker 镜像并推送到 Docker Hub
  • 敏捷开发中的自动化脚手架在 HarmonyOS 的应用
  • shardingsphere分库分表项目实践4-sql解析sql改写
  • 【Unity3D】ECS入门学习(八)块组件 ArchetypeChunk
  • 【运维】部署MKDocs
  • 【从零开始入门unity游戏开发之——C#篇37】进程、线程和C# 中实现多线程有多种方案
  • Linux arm 编译安装glibc-2.29