(转)Golang中自动“取引用”和“解引用”对原值的影响

原文:https://blog.csdn.net/u014633283/article/details/83902020

1. 写在前面
我们知道Golang在调用方法时,会自动对实参进行“取引用”或“解引用”操作。我们在前面的博客Golang对方法接收者变量的自动“取引用”和“解引用”中也已经讨论了容易引起混淆的解/取引用和接口相关的知识,这里我们将讨论另一个问题:“自动取引用”和“自动解引用”会不会对原值产生影响。
我们知道这样一个规则:

规则1: 当传递给方法的实参是一个值类型时,原值的内容不会受到影响,因为传递进来的是原值的副本;相反,当传递给方法的实参是一个指针类型时,原值的内容将可能受到影响。

但本文讨论一个比较特殊的情况是:“自动解引用”时receive会从指针类型转变为值类型,而“自动取引用”时receiver会从值类型转变为指针类型,这是否会对规则1产生影响。

2. 实验验证
我们还是用代码来说明问题。demo1.go分别演示了四种情形:

用值类型的实参调用形参为值类型的方法
用指针类型的实参调用形参为值类型的方法(会进行“自动解引用”)
用值类型的实参调用形参为指针类型的方法(会进行“自动取引用”)
用指针类型的实参调用形参为指针类型的方法
//demo1.go
package main

import "fmt"

// user defines a user in the program.
type user struct {
email string
}

// changeEmailByValue implements a method with a value receiver.
func (u user) changeEmailByValue(email string) {
u.email = email
}


// changeEmailByPointer implements a method with a pointer receiver.
func (u *user) changeEmailByPointer(email string) {
u.email = email
}

func main() {
alice := user{"alice@163.com"} // value type
fmt.Printf("Alice's original email:%s\n", alice.email)
alice.changeEmailByValue("alice@gmail.com")
fmt.Printf("ChangeEmailByValue with a value type: %s\n", alice.email)

bob := &(user{"bob@163.com"}) // pointer type
fmt.Printf("Bob's original email:%s\n", bob.email)
bob.changeEmailByValue("bob@gmail.com")
fmt.Printf("ChangeEmailByValue with a pointer type: %s\n", bob.email)

carol := user{"carol@163.com"} // value type
fmt.Printf("Carol's original email:%s\n", carol.email)
carol.changeEmailByPointer("carol@gmail.com")
fmt.Printf("ChangeEmailByPointer with a value type: %s\n", carol.email)

dave := &(user{"dave@163.com"}) // pointer type
fmt.Printf("Dave's original email:%s\n", dave.email)
dave.changeEmailByPointer("dave@gmail.com")
fmt.Printf("ChangeEmailByPointer with a pointer type: %s\n", dave.email)
}

代码运行结果如下图所示

 

 

 


3. 小结
从运行结果可以发现,“自动解引用”和“自动取引用”都不会改变规则1,方法的调用是否会对原值产生影响完全取决于该方法的形参是值类型还是参数类型。

posted @   liujiacai  阅读(150)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
历史上的今天:
2019-01-16 (转)Python 实现双向链表(图解)
2018-01-16 (转)linux正则表达式详解
点击右上角即可分享
微信分享提示