【问题标题】:Unmarshalling in-place into a slice type in Go在 Go 中就地解组为切片类型
【发布时间】:2022-01-15 07:01:57
【问题描述】:

经常在使用 go 的时候,不知道为什么,我有写类似的冲动

type data []event

尤其是当我知道我将在程序中的大部分内容没有过多考虑其内容的情况下传递切片时。迟早是时候将一些数据解压缩到那个事件片段中,我最终会写如下内容:

func (d *data)Unmarshal(b []byte){
  //... lots of sad code that never works
}

无论我做什么,我都无法完全弄清楚如何使用 unmarshal 方法来祝福我的切片类型,该方法将一些字节就地转换为 data 类型。

当我放弃的时候,我要么写一个更简单的函数,比如func UnmarshalData(b []byte) data,感觉像是退路,很难写接口,要么先改变类型,然后做一个类似的结构

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。为什么它不起作用?我误会了什么?

【问题讨论】:

标签: go slice


【解决方案1】:

Unmarshal 函数的最后一行是覆盖接收器本身,即它的地址:

f = &my_f // changing the value of the pointer

更新后的值不会传播给调用者。来自Declarations and Scope

表示方法接收器、函数参数或结果变量的标识符的范围是函数体

您必须改变指向的值,然后调用者将在取消引用时看到它。 (其实不用转换成定义好的切片类型)

func (f *foo) Unmarshal(s string) {
    // ...
    integers := make([]int, len(numbers))
    *f = integers
}

固定游乐场:https://go.dev/play/p/3JayxQMClt-

【讨论】:

    猜你喜欢
    • 2012-11-10
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多