我正在try 编写一个函数来修改通过指针传递的原始贴图,但是GO不允许这样做.假设我有一张很大的 map ,不想来回复制.

使用按值传递的代码正在工作,正在做我需要的事情,但涉及到按值传递(playground):

package main

import "fmt"

type Currency string

type Amount struct {
    Currency Currency
    Value float32
}

type Balance map[Currency]float32

func (b Balance) Add(amount Amount) Balance {
    current, ok := b[amount.Currency]
    if ok {
        b[amount.Currency] = current + amount.Value
    } else {
        b[amount.Currency] = amount.Value
    }
    return b
}

func main() {
    b := Balance{Currency("USD"): 100.0}
    b = b.Add(Amount{Currency: Currency("USD"), Value: 5.0})

    fmt.Println("Balance: ", b)
}

但是如果我try 将参数作为指针传递,如下面的(playground):

func (b *Balance) Add(amount Amount) *Balance {
    current, ok := b[amount.Currency]
    if ok {
        b[amount.Currency] = current + amount.Value
    } else {
        b[amount.Currency] = amount.Value
    }
    return b
}

我发现编译错误:

prog.go:15: invalid operation: b[amount.Currency] (type *Balance does not support indexing)
prog.go:17: invalid operation: b[amount.Currency] (type *Balance does not support indexing)
prog.go:19: invalid operation: b[amount.Currency] (type *Balance does not support indexing)

我该怎么处理这件事呢?

推荐答案

您正在try 对指针而不是 map 本身进行索引.有点令人困惑,因为通常使用指针而不是值, struct 的取消引用是自动的.但是,如果您的 struct 只是一个映射,那么无论如何它都是通过引用传入的,因此您不必担心创建作用于指针的方法,以避免每次都复制整个 struct .下面的代码等同于您的第一个代码段,但使用的是指针类型.

package main

import "fmt"

type Currency string

type Amount struct {
    Currency Currency
    Value float32
}

type Balance map[Currency]float32

func (b *Balance) Add(amount Amount) *Balance {
    current, ok := (*b)[amount.Currency]
    if ok {
        (*b)[amount.Currency] = current + amount.Value
    } else {
        (*b)[amount.Currency] = amount.Value
    }
    return b
}

func main() {
    b := &Balance{Currency("USD"): 100.0}
    b = b.Add(Amount{Currency: Currency("USD"), Value: 5.0})

    fmt.Println("Balance: ", (*b))
}

但是要回答如何处理它:如果您的 struct 只是map类型,我就不会担心编写接收函数来接受指针,而只是接收值,因为值无论如何都只是一个引用.在您的原始代码段中执行类似操作.

Go相关问答推荐

我不能让GIO画一个按钮

困扰围棋官方巡回赛的S建议所有方法都使用同一类型的接收器

使用GO从RDPMC获得价值

为什么没有正确生成这些元组?

如何在正则表达式中使整个单词可选?

如何根据地址和大小打印字符串

使用 OpenTelemetry 统一不同服务的范围

如何使用 go-git 将特定分支推送到远程

Golang crypto/rand 线程安全吗?

使用 go.work 文件在多个测试文件上运行 go test 命令

将 .gz 文件添加到 tar.gz 文件,但在添加之前解码 gz.输出文件被剪辑(损坏)

Golang - 客户 Unmarshaler/Marshaler 在指针上具有 nil/null 值

级联调用泛型函数时的泛型类型推断

当有多个同名包时如何在vscode中显示golang包完整路径?

go 是否对 struct 使用空间填充之类的东西?

在 Golang 中获取谷歌云服务帐户的访问令牌?

有没有办法在一个 goroutine 返回后延迟后取消上下文?

go mod tidy 错误消息:但是 go 1.16 会 Select

处理程序中的无限循环

Go generics:我会在哪里使用 any 而不是 interface{}?