Golang Go语言中的小白问题请教

发布于 1周前 作者 vueper 来自 Go语言

Golang Go语言中的小白问题请教

请教一个 Go 的小白问题

( A ) func DoSomething(a *A) {
        b = a
    }

( B ) func DoSomething(a A) {
        b = &a
    }
   

这两个函数调用的区别具体是什么呢

26 回复

A:引用传递
B:值传递

更多关于Golang Go语言中的小白问题请教的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


A:传进来的是那个结构体的内存地址(吧?)
B:通俗来说传入的 a 是 new 了一个一个零值的结构体,然后在把你传的结构赋值上去。

例如 a 现在的地址为 0x0000000001 值为 1
( A ) 函数中的 a 地址是 0x0000000002 但是 a 的值是 0x0000000001
( B ) 函数中的 a 地址是 0x0000000003 但是 a 的值是 1

*A 是 A 的指针类型

在函数里面修改 b 的值 然后在此函数外面看看 a 的值是否也被改了

(A) 是 point receiver, https://go.dev/tour/methods/4

如果对 b 做修改,外面 a 指向的值也会变。

( B )这样写意义不大。b = &a 中的 a 已经是调用时参数 a 的一个 copy ,再取它的指针没什么意义,因为修改了 b 不是影响到外面的 a 。

理论上说 go 是没用引用传递的,只有指针传递,指针传递和引用传递是有区别的


一个传进来的东西是指针类型,一个是传值进来取地址然后给 b 。
这差异够大了吧,一个是标识符取地址,一个是指针本身。
&a = 0x02 &c =0x01 c = 1 *a = 1 a=0x01.
1.b = 0x01 = &c
2.b = &a = 0x02

建议点说就是第一种你改*b 他能影响到外面。
第二种你只能改 b 他影响不到外面。
想要不改数据对外传递处理信息用第二种,想要处理信息顺手改外面传指针进去。

要明白这个问题,先要了解引用数据类型,是怎么在内存中存储的。一个 T 类型的对象 t ,实际上需要开辟两种不同的内存空间来存储,t 在栈内存中,而对应的值是在堆内存中。*T 是指向堆内存地址的指针;而&t ,则是栈内存中 t 的地址。

c 语言没学过?

A 这个原始值后续可能会改变,需要同步变化时用。
后续 b=a

B 干净调用,b 是 a 的副本,后续 a 和 b 没有交集。

A:指针传递,可修改其值
B:值传递,不可修改

对于 go 来说,若你想修改某个参数的值,就需要拿到其指针

与 c/c++中指针与值概念是一样的,只是用起来没有心理负担

go 里面没有引用传参,都是值传递

是的 。老哥说的对 。指针地址也是值 。仅此而已

B 属于脱裤子放屁了

  1. 先解释 Golang 的值传递, 注意任何情况下都是值传递, 但是这个值可能是一个地址, 举个例子, 某东有卖螃蟹的, 但是很多是卖的螃蟹券, 我买了螃蟹券, 然后送了人, 那是不是可以说买了螃蟹送礼, 可以, 不过最终需要那个人自提而已
    1. 有没有办法证明 Golang 是值传递,
    golang<br>package main<br><br>import "fmt"<br>type demo struct{}<br><br>func test(arg interface{}) {<br> fmt.Printf("in func test %p\n", &amp;arg)<br>}<br><br><br><br>func main() {<br> d := demo{}<br> fmt.Printf("out of test %p\n", &amp;d)<br> test(d)<br><br> fmt.Printf("out of test %p\n", &amp;d)<br> test(&amp;d)<br><br> s := []int{1,2,}<br> fmt.Printf("out of test %p\n", s)<br> test(s)<br><br> m := map[string]int{"1":1}<br> fmt.Printf("out of test %p\n", m)<br> test(m)<br>}<br><br>/*<br>out of test 0x116ce80<br>in func test 0xc000010230<br>out of test 0x116ce80<br>in func test 0xc000010240<br>out of test 0xc0000160c0<br>in func test 0xc000010250<br>out of test 0xc000074180<br>in func test 0xc000010260<br>*/<br>
    2. slice/map 是引用类型, 害, 你就把他当个螃蟹券
    3. 题中两个区别
    i). 开销不同, a 中值需要赋值一次地址, 开销很小, b 中需要复制一次结构体
    ii). 虽然看起来效果一样, 但是 b 中的 a 跟已经跟外面的 a 不是一个东西了, 因为有一次拷贝, 完完全全就是两个东西

目测这个问题是在看完 the way to go 以后发现的吧

指针不是 引用传参 ?

先学习*和&代表了啥.*是指针,&是取地址.学习 go 之前先去学一下 c 的指针那块内容,就不会被这个搞晕.
int var_runoob = 10;
int *p; // 定义指针变量
p = &var_runoob;//取出 var_runoob 指向的地址赋值给 p
printf(“p 的值: %p\n”, p);
p 的值:0x7ffeeaae08d8

大佬们学习了,大学学 C 的时候就是指针谜,现在还是



golang 只有值传递

当然,很高兴能帮助解答关于Go语言的问题!以下是针对“Golang Go语言中的小白问题请教”的回复:


你好,很高兴你对Go语言感兴趣!作为初学者,遇到疑问是很正常的。以下是一些常见的Go语言入门问题及简要解答,希望能帮到你:

  1. 安装与环境配置:确保你已经正确安装了Go语言环境,可以通过命令行输入go version来检查版本信息。

  2. 基础语法:Go语言注重简洁和明确,建议从变量声明、数据类型、控制结构(如if-else、for循环)等基础语法开始学习。

  3. 并发编程:Go语言以并发编程著称,goroutine和channel是必学的概念。它们使得并发编程变得更加简单和高效。

  4. 标准库与第三方库:Go语言的标准库非常强大,涵盖了文件操作、网络编程、JSON解析等多个方面。同时,也有很多优秀的第三方库可供使用。

  5. 实践项目:理论学习之后,最好通过实际项目来加深理解。可以从简单的命令行工具开始,逐步挑战更复杂的项目。

  6. 学习资源:推荐《Go语言编程》一书,以及Go语言的官方文档和教程。此外,GitHub上的开源项目和社区也是很好的学习资源。

如果遇到具体的问题或代码上的困惑,不妨贴出来,大家可以一起讨论和解决。祝你学习愉快!


希望这个回复能帮到你,如果有更具体的问题,欢迎随时提问。

回到顶部