英文:
map of sets initialization (Go)
问题
以下是翻译好的内容:
下面的 Golang 代码根据以下形式的输入,为每个食谱收集一组营养物质:
# applepie
- 面粉
- 苹果
- 鸡蛋
# pizza
- 面粉
- 奶酪
- 鸡蛋
- 番茄
它在 (2) 处报错 assignment to entry in nil map
。
但是为什么呢?每个“子映射”在 (1) 处都使用 make
进行了初始化?
package main
import (
"bufio"
"fmt"
"os"
"regexp"
)
func main() {
nutriments := map[string][]string{
"flour": {"sugars"},
"egg": {"protein", "fat"},
"tomato": {"water", "viamins"},
"cheese": {"calcium", "protein"},
"apple": {"sugars", "fiber", "vitamin"},
}
total := make(map[string]map[string]bool)
f := bufio.NewScanner(os.Stdin)
currentRecipe := ""
for f.Scan() {
Line(f.Text(), currentRecipe, nutriments, total)
}
fmt.Println(total)
}
func Line(line, currentRecipe string, nut map[string][]string, tot map[string]map[string]bool) {
if foundrec, _ := regexp.MatchString("^# [[:graph:]]+", line); foundrec { // 开始食谱
currentRecipe := line[2:]
fmt.Println("---------", currentRecipe) // 更新当前食谱
tot[currentRecipe] = make(map[string]bool) // <== 初始化集合 (1)
}
if foundnut, _ := regexp.MatchString("^- [[:graph:]]+", line); foundnut { // 新成分
nutri := line[2:]
tot[currentRecipe][nutri] = true // <===== 这里 (2)
}
}
英文:
Below Golang code gathers a set of nutriments for each recipe, based on an input of this form:
# applepie
- flour
- apple
- egg
# pizza
- flour
- cheese
- egg
- tomato
It complains at (2) of assignment to entry in nil map
.
But why ? Each "submap" is howhever initialized with the make
at (1) ?
package main
import (
"bufio"
"fmt"
"os"
"regexp"
)
func main() {
nutriments := map[string][]string{
"flour":{"sugars"},
"egg":{"protein", "fat"},
"tomato":{"water", "viamins"},
"cheese":{"calcium", "protein"},
"apple":{"sugars", "fiber", "vitamin"} }
total := make(map[string]map[string]bool)
f := bufio.NewScanner(os.Stdin)
currentRecipe := ""
for f.Scan() {
Line(f.Text(), currentRecipe, nutriments, total)
}
fmt.Println(total)
}
func Line (line, currentRecipe string, nut map[string][]string, tot map[string]map[string]bool) {
if foundrec, _ := regexp.MatchString("^# [[:graph:]]+", line); foundrec { // Begin recipe
currentRecipe := line[2:]
fmt.Println("---------", currentRecipe) // update current
tot[currentRecipe] = make(map[string]bool) // <== INITIALIZE SET (1)
}
if foundnut, _ := regexp.MatchString("^- [[:graph:]]+", line); foundnut { // New ingredient
nutri := line[2:]
tot[currentRecipe][nutri] = true // <===== HERE (2)
}
}
答案1
得分: 1
根据评论中指出的问题,问题出在对currentRecipe的更新机制上。字符串是按值传递的。
以下是正确的代码:
package main
import (
"bufio"
"fmt"
"os"
"regexp"
)
func main() {
nutriments := map[string][]string{
"flour": {"sugars"},
"egg": {"protein", "fat"},
"tomato": {"water", "viamins"},
"cheese": {"calcium", "protein"},
"apple": {"sugars", "fiber", "vitamin"},
}
total := make(map[string]map[string]bool)
f := bufio.NewScanner(os.Stdin)
var currentRecipe string
for f.Scan() {
currentRecipe = Line(f.Text(), currentRecipe, nutriments, total)
}
fmt.Println(total)
}
func Line(line, currentRecipe string, nut map[string][]string, tot map[string]map[string]bool) string {
if foundrec, _ := regexp.MatchString("^# [[:graph:]]+", line); foundrec { // Begin recipe
currentRecipe = line[2:]
fmt.Println("---------", currentRecipe) // update current
tot[currentRecipe] = make(map[string]bool) // prepare set
}
if foundnut, _ := regexp.MatchString("^- [[:graph:]]+", line); foundnut { // Begin ingredients list
nutri := line[2:]
tot[currentRecipe][nutri] = true
}
return currentRecipe
}
希望对你有帮助!
英文:
As pointed in comments, problem was lying in the update mechanism for currentRecipe. string was passed by value.
Here is correct code
package main
import (
"bufio"
"fmt"
"os"
"regexp"
)
func main() {
nutriments := map[string][]string{
"flour":{"sugars"},
"egg":{"protein", "fat"},
"tomato":{"water", "viamins"},
"cheese":{"calcium", "protein"},
"apple":{"sugars", "fiber", "vitamin"} }
total := make(map[string]map[string]bool)
f := bufio.NewScanner(os.Stdin)
currentRecipe := ""
for f.Scan() {
currentRecipe = Line(f.Text(), currentRecipe, nutriments, total)
}
fmt.Println(total)
}
func Line (line, currentRecipe string, nut map[string][]string, tot map[string]map[string]bool) string {
if foundrec, _ := regexp.MatchString("^# [[:graph:]]+", line); foundrec { // Begin recipe
currentRecipe = line[2:]
fmt.Println("---------", currentRecipe) // update current
tot[currentRecipe] = make(map[string]bool) // prepare set
}
if foundnut, _ := regexp.MatchString("^- [[:graph:]]+", line); foundnut { // Begin ingredients list
nutri := line[2:]
tot[currentRecipe][nutri] = true
}
return currentRecipe
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论