亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go:無效操作 - 類型 *map[key]value 不支持索引

Go:無效操作 - 類型 *map[key]value 不支持索引

Go
尚方寶劍之說 2022-01-04 09:51:26
我正在嘗試編寫一個函數來修改由指針傳遞的原始地圖,但 Go 不允許這樣做。假設我有一張大地圖,不想來回復制。使用按值傳遞的代碼正在運行并且正在執行我需要的操作,但涉及按值傳遞(操場):package mainimport "fmt"type Currency stringtype Amount struct {    Currency Currency    Value float32}type Balance map[Currency]float32func (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)}但是,如果我嘗試像這里(操場)那樣將參數作為指針傳遞: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)我該如何處理?
查看完整描述

2 回答

?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

您正在嘗試索引指針而不是地圖本身。有點令人困惑,因為通常指針與值解引用對于結構來說是自動的。但是,如果您的結構只是一個映射,那么它無論如何只能通過引用傳入,因此您不必擔心創建對指針起作用的方法以避免每次都復制整個結構。以下代碼等效于您的第一個代碼段,但使用的是指針類型。


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))

}

但是要回答如何處理它:如果您的結構只是映射類型,我不會擔心編寫您的接收函數來獲取指針,并且只接收值,因為無論如何該值只是一個引用。在你的原始片段中做喜歡。


查看完整回答
反對 回復 2022-01-04
?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

您可以簡單地取消引用b:(*b)


https://play.golang.org/p/Xq6qFy4_PC


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

}

更新

@Serdmanczyk 提出了一個很好的觀點......您可以安全地按值傳遞地圖,底層地圖將被更新,而不是地圖的副本。也就是說; 在映射的情況下按值傳遞意味著傳遞映射的地址,而不是映射的內容。


見https://play.golang.org/p/i7Yz4zMq4v


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"}



查看完整回答
反對 回復 2022-01-04
  • 2 回答
  • 0 關注
  • 233 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號