One minute
Golang Byvalue
最近同事在设计 interceptor的时候, 发现 resp 通信层修改后, 并没有上传到 业务逻辑层, 后来发现是 调入了 golang 传值的陷阱中去了. 这里写一个例子一起review下golang传值的特点.
package main
import (
"fmt"
)
type Message struct{
Topic string
Body []byte
switcher bool
}
func doInt(resp interface{}) {
resp = &Message{
Topic: "hahha",
Body: []byte("heiya heiya"),
}
}
func doStruct(resp *Message) {
resp = &Message{
Topic: "hahha",
Body: []byte("heiya heiya"),
}
}
func doField(resp *Message) {
resp.Topic = "haha"
resp.Body = []byte("lalal")
resp.switcher = true
}
func main() {
r := new(Message)
doInt(r)
fmt.Printf("after interface, msg: %v\n", r)
r1 := new(Message)
doStruct(r1)
fmt.Printf("after struct, msg: %v\n", r1)
r2 := new(Message)
doField(r2)
fmt.Printf("after field. msg: %v\n", r2)
}
在运行后, 会惊讶的发现:
after interface, msg: &{ [] false}
after struct, msg: &{ [] false}
after field. msg: &{haha [108 97 108 97 108] true}
因为在两种场景中, 传参是直接指向了另一块内存, 根据传值引用的特性, 虽然修改了 传参, 但是因为是传值的行为, 所以并不会透传到 使用者。第三种情况, 虽然也是传值类型, 但是参数和入参都是指向同一块内存的, 所以, 这里的修改, 实际上修改的是内存地址上的值, 因此使用者是可以感知的.
139 Words
2019-07-03 13:39 +0800