C语言对函数解引会怎样,关于go语言编译器自动解引用

关于go语言编译器自动解引用

用值类型的实参调用形参为值类型的方法

用指针类型的实参调用形参为值类型的方法(会进行“自动解引用”)

用值类型的实参调用形参为指针类型的方法(会进行“自动取引用”)

用指针类型的实参调用形参为指针类型的方法

我们还是用代码来说明问题。

type node struct {

Name string

Next *node

}

// 用c语言翻译,

// void Say(node* n) { printf("%d

", 123); }

func (n *node) Say() {

fmt.Println(123)

}

// 用c语言翻译,

// void Say(node n) { printf("%d

", 123); }

func (n node) Say2() {

fmt.Println(2333)

}

func main() {

n1 := &node{Name: "hui"}

n1.Say()

n1.Say2() // Say2()是值接收器 (*n1).Say2() go编译器为我们加上* 自动解引用

n2 := node{Name: "hui"}

n2.Say() // Say()是指针接收器 (&n2).Say() go编译器为我们加上& 自动取引用

n2.Say2()

}

记住两点

go语言只有值传递,指针也是值传递。

值类型接收器、指针类型接收器 可以理解为函数 的 一个形参。结合c语言如何做,对于c语言来说传值、传指针哪种会改变实参。

关键理解:当传递给方法的形参是一个值类型时(值类型接收器),原值的内容不会受到影响,因为值传递,传递进来的是原值的复制副本(形参是副本);相反,当方法的形参是一个指针类型时,原值的内容将可能受到影响,因为传递的是指针类型复制,虽然是复制但是指针中存储的地址仍然是实参的真实地址。

一个链表节点删除的例子

以链表节点删除问题为例,由于在go语言中都是参数都是值传递,所以在链表操作的时候不能直接操作形参来修改原来指针的内容,但可以修改其指向的内容为什么呢,用代码来解释

type node struct {

Name string

Next *node

}

func main() {

n1 := &node{Name: "zgh"}

n2 := &node{Name: "dev"}

n3 := &node{Name: "devaaa"}

n1.Next = n2

n2.Next = n3

n3.Next = nil

ts(n2)

data := make([]string, 0)

for n1 != nil {

data = append(data, n1.Name)

n1 = n1.Next

}

fmt.Println(data)

}

func ts(n *node) {

// 方式一: out: [hui dev devaaa] 不会删除

n = n.Next // 这里的n是一个指针的复制,此操作只会更改形参n指针的指向,不会更改实参的指向,如果想修改实参的指向,只能用方式二

// 方式二: out: [hui devaaa]

//*n = *n.Next // 会更改实参,也就是被复制的指针

// 方式三: out: [hui asada]

// 这种方式会更改实参,为什么呢 因为这里go语言的编译器会为你加上*来解引用

//n.Next= n.Next.Next // 实际(*n).Next=

//n.Name = "asada" // 实际(*n).Name=

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值