mapの値に構造体を入れたらエラーが・・・
先日、職場でこんな感じのコードを書いたらエラー。(コードはサンプルです)
umaimono.go
package main
import "fmt"
type Food struct {
ID int
Name string
Description string
}
func main(){
fmt.Println(MakeResult()["うまいもの"])
}
func MakeResult() map[string]Food {
result := make(map[string]Food)
result["うまいもの"] = Food{
ID: 1,
Name: "焼肉",
}
result["うまいもの"].Description = "すこぶるうまい"
return result
}
これを実行すると cannot assign to struct field result["うまいもの"].Description in map
というエラー。なんでや〜。
ポインタ型にしたら解決
色々とググった結果、構造体をポインタ型にしたら解決した。
理屈は一旦置いておいて、これでうまくいく。
umaimono.go
package main
import "fmt"
type Food struct {
ID int
Name string
Description string
}
func main(){
fmt.Println(*MakeResult()["うまいもの"])
}
func MakeResult() map[string]*Food {
result := make(map[string]*Food)
result["うまいもの"] = &Food{
ID: 1,
Name: "焼肉",
}
result["うまいもの"].Description = "すこぶるうまい"
return result
}
結果:{1 焼肉 すこぶるうまい}
無事に説明が追加された。
どうしてもポインタ型で返したくない場合は?
他の機能との兼ね合いで、どうしてもポインタ型で返したくないという場合もあるかもしれない。
そんな時は、こう。(自分が思いついたのではなく、先輩がこうしていた)
umaimono.go
package main
import "fmt"
type Food struct {
ID int
Name string
Description string
}
func main(){
fmt.Println(MakeResult()["うまいもの"])
}
func MakeResult() map[string]Food {
pointerResult := make(map[string]*Food)
pointerResult["うまいもの"] = &Food{
ID: 1,
Name: "焼肉",
}
pointerResult["うまいもの"].Description = "すこぶるうまい"
result := make(map[string]Food)
for k, v := range pointerResult{
result[k] = *v
}
return result
}
なるほどなあ。
#最後に
無事、焼肉はうまいという結果を返す関数が実装できましたね。うれしいです。
ちなみに今回がQiita初投稿なので、どういう口調で書けば良いのかなどが色々と分からない感じでしたが、最後まで読んでくださってありがとうございます。