指针传参,如果通过解引用获得原值后直接修改属性,则外层属性也会修改。这个很好理解。但为什么再赋值一次,就不是这样的结果呢?
有如下代码
package main
func main() {
person := Person{age: 10}
person2 := *(&person)
person2.age = 30
println(person.age)
println(person2.age)
println("======")
setAgeByPointer(&person)
println(person.age)
println("======")
setAge(&person)
println(person.age)
}
type Person struct {
age int
}
func setAgeByPointer(person *Person) {
person2 := *person
person2.age = 55
}
func setAge(person *Person) {
(*person).age = 55
}
最后的输出结果是这样
10
30
======
10
======
55
一个是
person2 := *person
person2.age = 55
另一个是 (*person).age = 55
为什么上面那个没有修改原值,下面修改了原值,我理解此时都直接修改了原内存地址里的值呀
第一个和第二个的区别是,第一个是被赋值了,但是被赋值的是person的副本,而不是地址引用-指针,所以被赋值的那个person2修改age,只会影响到person2而已,不会影响person本身。
第二个的虽然也用了&
和*
去折腾了一圈,但是还是本身person
,所以你修改age,其实还是对person
的修改。
给你增加个例子,这个其实虽然 person3
也是被赋值,但是被赋的是person的指针,也就是内存地址。所以你对person3的修改,其实就是对person本身的修改。
person3 := &person
person3.age = 1000
println(person3.age, person.age)
person2 := *person
中是先取出person的值然后赋给person2,在Go中struct是值传递的。person := &Person{age:10}
创建则它是指针类型,此时person2 := person
,然后修改person2.age会让person.age一起改变。深拷贝
和浅拷贝
进行了解。func main() {
person := Person{age: 10}
person2 := *(&person) // 创建 person 的副本
person2.age = 30 // 修改 person2 的 age 属性
fmt.Println(person.age) // 打印 person.age,结果为 10
fmt.Println(person2.age) // 打印 person2.age,结果为 30
setAgeByPointer(&person) // 传递 person 的指针
fmt.Println(person.age) // 打印 person.age,结果为 10
setAge(&person) // 传递 person 的指针
fmt.Println(person.age) // 打印 person.age,结果为 55
}
func setAgeByPointer(person *Person) {
person2 := *person // 创建 person 的副本
person2.age = 55 // 修改 person2 的 age 属性
}
func setAge(person *Person) {
(*person).age = 55 // 直接修改 person 的 age 属性
}
graph TD;
A[main 函数开始] --> B[创建 person: Person{age: 10}]
B --> C[person2 := *(&person)]
C --> D[person2.age = 30]
D --> E[打印 person.age: 10]
D --> F[打印 person2.age: 30]
E --> G[调用 setAgeByPointer(&person)]
G --> H[person2 := *person]
H --> I[person2.age = 55]
I --> J[打印 person.age: 10]
J --> K[调用 setAge(&person)]
K --> L[(*person).age = 55]
L --> M[打印 person.age: 55]
person2 := *(&person)
时,person2
是 person
的一个副本。修改 person2
不会影响 person
的值。setAgeByPointer
函数中,person2 := *person
同样是创建了 person
的一个副本。因此,修改 person2
不会影响原始的 person
。setAge
函数中,(*person).age = 55
直接修改了 person
的 age
属性,因为 person
是通过指针传递的,修改指针指向的值会影响原始变量。person2 := *person
这行代码通过解引用person
得到一个新的Person
值,并赋给person2
。此时person2
是person
的一个副本,任何对person2
的修改都不会影响person
。(*person).age = 55
这行代码通过指针修改了person
的age
。由于这里是直接操作指向原始数据的内存地址,因此修改会反映到原始对象上。
在 Go 语言中,所有的参数传递都是通过值传递的方式进行的,都是传递副本。
关于指针和解引用赋值的行为不要混淆。
我有我的函数,我正在那里填充,但调用这个函数后没有填充,但我知道它是在这个函数中填充的,因为我有那里的输出代码。 我像这样传递指针 为什么它不起作用?谢谢
问题内容: 我正在浏览位于http://tour.golang.org/的golang教程,并在示例29中进行了一些实验。 供您参考,原始示例复制到此处: 这很基本,它显示了如何创建该新结构实例。 但是,示例28显示了如何通过指向它的指针来操纵顶点,因此我对示例进行了一些修改,并对输出感到惊讶。这是修改: 并输出: 使我感到惊讶的不是{4,2},这似乎意味着更改更改了所指向的结构的实例。来自C /
本文向大家介绍为什么我们在C ++中通过引用传递指针?,包括了为什么我们在C ++中通过引用传递指针?的使用技巧和注意事项,需要的朋友参考一下 如果需要修改指针而不是指针指向的对象,则可以按引用传递指针。 这是如何通过引用传递指针的示例- 示例 输出结果
Go 函数 引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 引用传递指针参数传递到函数内,以下是交换函数 swap() 使用了引用传递: /* 定义交换值函数*/ func swap(x *int, y *int) { var temp int temp = *x /* 保持 x 地址上的值 */ *x = *y
在使用一个库的时候碰到了一个很奇怪的问题,有个class实例化生成的对象,假设为A 对A的属性进行修改 打印A发现,其中的a属性并没有变,但是直接打印A.a是改变了的,请问这种情况大概会是什么原因呢,是有什么知识盲区吗,目前知道a属性是不可删除的属性,但是一般对象设置configurable=false也不会出现这种情况,如果不允许修改的话应该也会报错。。 (PS:A只是为了表述简化的例子,并不是
上节课我们学习了 Go 语言中的两种变量声明方式:单变量声明方式和多变量声明方式。既然已经声明了变量,那么下一步肯定要给变量赋值并使用,这节课我们就来学习下在 Go 语言中如何给一个变量赋值: 1. 单变量赋值 Go 语言的赋值使用的是 = 符号,赋值过程可以在变量声明时赋值,也可以在变量声明之后赋值,如果在变量声明时直接赋值,可以不用声明变量类型。需要注意的是 Go 语言变量声明之后会初始化一个
问题内容: 我可以使用指针和值嵌入golang中。通过指针 按价值 通过指针或值更喜欢什么? 问题答案: 这取决于。这里有几种可能性。 如果Renderer按值传递,并且在 Bitmap上定义了Bitmap所需的方法,则需要嵌入 Bitmap。 如果将Renderer作为指针传递,则可以将Bitmap作为值嵌入而没有任何问题(在这种情况下仍可以访问指针方法)。 如果Bitmap具有返回指针的构造函
Go支持指针,可以用来给函数传递变量的引用。 package main import "fmt" // 我们用两个不同的例子来演示指针的用法 // zeroval函数有一个int类型参数,这个时候传递给函数的是变量的值 func zeroval(ival int) { ival = 0 } // zeroptr函数的参数是int类型指针,这个时候传递给函数的是变量的地址 // 在函数内部对