在 Go 中就地解组为切片类型
Unmarshalling in-place into a slice type in Go
经常在使用go的时候,不知道为什么,有一种想写类似
的冲动
type data []event
尤其是当我知道我将在不考虑太多程序的大部分内容的情况下传递切片时。迟早是时候将一些数据解包到那部分事件中,我最终会写类似这样的东西:
func (d *data)Unmarshal(b []byte){
//... lots of sad code that never works
}
无论我做什么,我永远无法完全弄清楚如何使用一种将一些字节就地转换为 data
类型的解组方法来祝福我的切片类型。
当我放弃的时候,我要么写一个像func UnmarshalData(b []byte) data
这样的更简单的函数,感觉像一个撤退,让编写接口变得困难,要么首先改变类型并制作一个像[=]这样的结构17=]
type data struct {
actuallyTheData []event
}
这感觉像是样板文件,纯粹是为了弥补我的理解不足。
所以我的问题是:是否可以编写一个带有指针接收器的函数,其中接收器是切片类型并且允许我例如就地解组?
我能得到的最接近的结果是:
type foo []int
func (f *foo) Unmarshal(s string) {
numbers := strings.Split(s, ",")
integers := make([]int, len(numbers))
for i, n := range numbers {
integer, err := strconv.Atoi(n)
if err != nil {
log.Fatal(err)
}
integers[i] = integer
}
my_f := foo(integers)
f = &my_f
}
完整示例如下:https://go.dev/play/p/3q7qehoW9tm。为什么它不起作用?我误会了什么?
你的 Unmarshal
函数的最后一行是覆盖接收器本身,即它的地址:
f = &my_f // changing the value of the pointer
更新后的值不会传播给调用者。来自 Declarations and Scope:
The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
您必须改变所指向的值,然后调用者将在取消引用时看到它。 (事实上,您不必转换为定义的切片类型)
func (f *foo) Unmarshal(s string) {
// ...
integers := make([]int, len(numbers))
*f = integers
}
经常在使用go的时候,不知道为什么,有一种想写类似
的冲动type data []event
尤其是当我知道我将在不考虑太多程序的大部分内容的情况下传递切片时。迟早是时候将一些数据解包到那部分事件中,我最终会写类似这样的东西:
func (d *data)Unmarshal(b []byte){
//... lots of sad code that never works
}
无论我做什么,我永远无法完全弄清楚如何使用一种将一些字节就地转换为 data
类型的解组方法来祝福我的切片类型。
当我放弃的时候,我要么写一个像func UnmarshalData(b []byte) data
这样的更简单的函数,感觉像一个撤退,让编写接口变得困难,要么首先改变类型并制作一个像[=]这样的结构17=]
type data struct {
actuallyTheData []event
}
这感觉像是样板文件,纯粹是为了弥补我的理解不足。
所以我的问题是:是否可以编写一个带有指针接收器的函数,其中接收器是切片类型并且允许我例如就地解组?
我能得到的最接近的结果是:
type foo []int
func (f *foo) Unmarshal(s string) {
numbers := strings.Split(s, ",")
integers := make([]int, len(numbers))
for i, n := range numbers {
integer, err := strconv.Atoi(n)
if err != nil {
log.Fatal(err)
}
integers[i] = integer
}
my_f := foo(integers)
f = &my_f
}
完整示例如下:https://go.dev/play/p/3q7qehoW9tm。为什么它不起作用?我误会了什么?
你的 Unmarshal
函数的最后一行是覆盖接收器本身,即它的地址:
f = &my_f // changing the value of the pointer
更新后的值不会传播给调用者。来自 Declarations and Scope:
The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
您必须改变所指向的值,然后调用者将在取消引用时看到它。 (事实上,您不必转换为定义的切片类型)
func (f *foo) Unmarshal(s string) {
// ...
integers := make([]int, len(numbers))
*f = integers
}