Golang中Map键验证问题探讨

Golang中Map键验证问题探讨 你好,

我对Go语言还比较陌生,正在做我的第一个项目,到目前为止进展得相当顺利。然而,我现在遇到了一个关于映射键验证的奇怪问题。我正在尝试创建一个简单的抽认卡应用程序,它会先询问卡片,然后询问定义。如果卡片或定义已经存在,它应该抛出一个错误并让用户重新输入该术语。以下是我的代码(我已删除了不必要的部分):

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {

	fmt.Println("Flash Cards v. 1.0")

	var choice string
	var card string
	var definition string
	cards := make(map[string]string)

	for {
		fmt.Println("Input the desired action (add, remove, import, export, ask, exit):")
		fmt.Scan(&choice)

		switch choice {
		case "add":
			scanner := bufio.NewScanner(os.Stdin)
			scanner.Scan()
			for {
				fmt.Println("The card: ")
				scanner.Scan()
				card = scanner.Text()
				if _, ok := cards[card]; ok {
					fmt.Printf("The card %s already exists. Try again:\n", card)
					scanner.Scan()
					card = scanner.Text()
				}
				fmt.Println("The definition for the card:")
				scanner := bufio.NewScanner(os.Stdin)
				scanner.Scan()
				definition = scanner.Text()
				if _, ok := cards[definition]; ok {
					fmt.Printf("The definition %s already exists. Try again:\n", definition)
					scanner.Scan()
					definition = scanner.Text()
				}
				cards[card] = definition
				fmt.Printf("The pair %q:%q has been added\n", card, definition)
				break
			}
		case "remove":
		case "import":
		case "export":
		case "ask":
		case "exit":
		default:
			fmt.Println("Error. Please try again!")
		}
	}
}

程序运行正常。我输入add。它要求输入一张卡片,例如,我输入France。然后它要求输入定义,我输入Paris。我收到消息The pair France:Paris has been added并返回到菜单,再次输入add,它要求输入一张卡片。如果我现在再次输入France,我会收到错误提示The card France already exists. Try again.,所以如果我现在输入Germany,它会接受该条目并询问术语/定义。但如果我现在再次输入Paris,它会显示The pair Spain:Paris has been added.

然而,它本应给出一个警告,说明定义Paris已经存在,然后要求用户输入一个新的术语,就像上面处理Paris那样。我一直在查看代码和各种资料及文档,但没能找出原因。我确信这是我没有考虑到的一些小问题。

任何帮助都将不胜感激。

祝好,


更多关于Golang中Map键验证问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你好,

感谢你的回复。

我之前没有想到这一点。

由于我目前尚未处理反向查找,而只是遍历映射,所以我暂时会采用那个解决方案。数据量应该不大,最多包含5到10个键值对。这也只是课程中的一个挑战。虽然它将来可能会作为某些代码的参考或基础,但不太可能用于其他用途,更不用说在生产环境中了。😊

干杯

更多关于Golang中Map键验证问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你正在检查定义是否已经作为键存在于映射中,但却只将其作为值存储。这样永远不会成功。

你需要遍历映射中的所有值 for k, v := range cards { … },或者维护一个“反向查找映射”,将定义映射到其对应的卡片。

后者需要更多内存,而前者则会在你向映射中添加每个项目时增加运行时间。

问题出在验证定义是否已存在时,你检查的是 cards[definition],但 cards 是一个以卡片为键、定义为值的映射。这意味着 cards[definition] 实际上是在检查是否有一张卡片的名字等于当前定义,而不是检查定义是否已被使用。要验证定义是否唯一,你需要遍历映射的值来检查。

以下是修正后的代码示例,添加了一个辅助函数来检查定义是否已存在:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func definitionExists(cards map[string]string, definition string) bool {
    for _, def := range cards {
        if def == definition {
            return true
        }
    }
    return false
}

func main() {
    fmt.Println("Flash Cards v. 1.0")

    var choice string
    var card string
    var definition string
    cards := make(map[string]string)

    for {
        fmt.Println("Input the desired action (add, remove, import, export, ask, exit):")
        fmt.Scan(&choice)

        switch choice {
        case "add":
            scanner := bufio.NewScanner(os.Stdin)
            for {
                fmt.Println("The card: ")
                scanner.Scan()
                card = scanner.Text()
                if _, ok := cards[card]; ok {
                    fmt.Printf("The card %s already exists. Try again:\n", card)
                    continue
                }
                fmt.Println("The definition for the card:")
                scanner.Scan()
                definition = scanner.Text()
                if definitionExists(cards, definition) {
                    fmt.Printf("The definition %s already exists. Try again:\n", definition)
                    continue
                }
                cards[card] = definition
                fmt.Printf("The pair %q:%q has been added\n", card, definition)
                break
            }
        case "remove":
        case "import":
        case "export":
        case "ask":
        case "exit":
        default:
            fmt.Println("Error. Please try again!")
        }
    }
}

在这个修正版本中,definitionExists 函数遍历 cards 映射的所有值,检查是否有与输入定义匹配的项。如果找到,返回 true,否则返回 false。在 add 分支中,使用这个函数来验证定义的唯一性,如果定义已存在,则提示用户重新输入。同时,我移除了内部多余的 scanner 创建,并调整了循环逻辑以使用 continue 来重新提示输入,避免重复代码。

回到顶部