Go:无效操作-type*map[key]值不支持索引

Go:无效操作-type*map[key]值不支持索引,go,pass-by-reference,Go,Pass By Reference,我试图编写一个函数,修改指针传递的原始映射,但Go不允许这样做。假设我有一张大地图,不想来回复制 使用按值传递的代码正在工作,正在执行我需要的操作,但涉及按值传递(): 但如果我尝试像这里()那样将参数作为指针传递: 我发现编译错误: prog.go:15: invalid operation: b[amount.Currency] (type *Balance does not support indexing) prog.go:17: invalid operation: b[amount.

我试图编写一个函数,修改指针传递的原始映射,但Go不允许这样做。假设我有一张大地图,不想来回复制

使用按值传递的代码正在工作,正在执行我需要的操作,但涉及按值传递():

但如果我尝试像这里()那样将参数作为指针传递:

我发现编译错误:

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)

我应该如何处理这个问题?

您可以简单地取消对
b的引用:
(*b)

更新 @塞德曼奇克提出了一个很好的观点。。。您可以通过值安全地传递映射,基础映射将被更新,而不是映射的副本。就是说,;在映射的情况下,传递值意味着传递映射的地址,而不是映射的内容

哪些产出:

main.foo{"hello":"world"}
main.foo{"hello":"cruel world"}

您试图在指针上建立索引,而不是映射本身。有点让人困惑,因为通常指针和值的解引用对于结构来说是自动的。但是,如果您的结构只是一个映射,那么它只能通过引用传入,因此您不必担心创建作用于指针的方法,以避免每次复制整个结构。以下代码相当于您的第一个代码段,但使用了指针类型

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))
}
但要回答如何处理它:如果您的结构只是map类型,我就不必担心编写接收函数来获取指针,只接收值,因为值无论如何只是一个引用。喜欢原始代码片段。

可能重复的
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
}
type foo map[string]string

func main() {
    a := foo{}
    a["hello"] = "world"
    fmt.Printf("%#v\n", a)
    mod(a)
    fmt.Printf("%#v\n", a)

}

func mod(f foo) {
    f["hello"] = "cruel world"
}
main.foo{"hello":"world"}
main.foo{"hello":"cruel world"}
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))
}