Methods Go:对象在方法调用后不持久
我正在尝试为我正在编写的程序实现MarshalBinary和UnmarshalBinary,但在调用UnmarshalBinary之后,我的更改似乎不会持久 我的MWE:Methods Go:对象在方法调用后不持久,methods,go,arguments,Methods,Go,Arguments,我正在尝试为我正在编写的程序实现MarshalBinary和UnmarshalBinary,但在调用UnmarshalBinary之后,我的更改似乎不会持久 我的MWE: package main import ( "encoding/binary" "fmt" "strconv" ) type test struct { var1 uint32 var2 uint32 } func (self test) MarshalBinary() ([]by
package main
import (
"encoding/binary"
"fmt"
"strconv"
)
type test struct {
var1 uint32
var2 uint32
}
func (self test) MarshalBinary() ([]byte, error) {
tmp := make([]byte, 8)
binary.BigEndian.PutUint32(tmp[0:4], self.var1)
binary.BigEndian.PutUint32(tmp[4:8], self.var2)
return tmp, nil
}
func (self test) UnmarshalBinary(data []byte) error {
self.var1 = binary.BigEndian.Uint32(data[0:4])
self.var2 = binary.BigEndian.Uint32(data[4:8])
fmt.Printf("UMB\t%s\n", self.String())
return nil
}
func (self test) String() string {
return "test struct\tvar1 = 0x" +
strconv.FormatUint(uint64(self.var1), 16) +
"\tvar2 = " + strconv.FormatUint(uint64(self.var2), 16)
}
func main() {
in := test{
var1: uint32(0x39471208),
var2: uint32(0x45387182),
}
fmt.Printf("In\t%s\n", in.String())
bin, _ := in.MarshalBinary()
fmt.Printf("Bin\t0x%x\n", bin)
var out test
out.UnmarshalBinary(bin)
fmt.Printf("Out\t%s\n", out.String())
}
以及我的输出:
In test struct var1 = 0x39471208 var2 = 45387182
Bin 0x3947120845387182
UMB test struct var1 = 0x39471208 var2 = 45387182
Out test struct var1 = 0x0 var2 = 0
self
参数不是引用类型,因此在调用方法test.UnmarshalBinary()时,它是按值复制的,整个结构复制到堆栈上,并在UnmarshalBinary()返回时释放。从围棋之旅的幻灯片54中:
使用指针接收器有两个原因。第一,避免
复制每个方法调用的值(如果
类型是一个大结构)
(对于我来说,很难找到一个官方消息来源说接收者是通过价值传递的;有人知道更权威的吗?)
尝试更改接收器以接受指针接收器:
func (self *test) MarshalBinary() ([]byte, error) {
tmp := make([]byte, 8)
binary.BigEndian.PutUint32(tmp[0:4], self.var1)
binary.BigEndian.PutUint32(tmp[4:8], self.var2)
return tmp, nil
}
func (self *test) UnmarshalBinary(data []byte) error {
self.var1 = binary.BigEndian.Uint32(data[0:4])
self.var2 = binary.BigEndian.Uint32(data[4:8])
fmt.Printf("UMB\t%s\n", self.String())
return nil
}
func (self *test) String() string {
return "test struct\tvar1 = 0x" +
strconv.FormatUint(uint64(self.var1), 16) +
"\tvar2 = " + strconv.FormatUint(uint64(self.var2), 16)
}
您将看到更好的输出:
In test struct var1 = 0x39471208 var2 = 45387182
Bin 0x3947120845387182
UMB test struct var1 = 0x39471208 var2 = 45387182
Out test struct var1 = 0x39471208 var2 = 45387182
参数通过值传递,接收器是第一个参数的语法糖。因此,接收器按值传递。接收器按值传递:。