map数据类型的奇怪表现

huangapple go评论85阅读模式
英文:

Strange performing of map data type

问题

我正在尝试将一组值添加到一个映射数据类型中,并尝试打印出来。但是它的表现很奇怪。当我直接使用键调用映射时,它给出了正确的输出,但是当我将键存储在变量中然后调用它时,它没有给出任何输出。我无法弄清楚发生了什么,为什么会得到这种输出。有人可以帮我解决这个问题吗?

package main

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

func main() {
	type Authentication struct {
		password string
	}
	var authentication = map[string]Authentication{}

	var user1 Authentication
	user1.password = "abc"
	authentication["def"] = user1

	reader := bufio.NewReader(os.Stdin)
	usid := readString(reader)

	fmt.Println(authentication)
	fmt.Println(authentication[usid])
	fmt.Println(authentication["def"])
}

// 读取输入的函数
func readString(reader *bufio.Reader) string {
	s, _ := reader.ReadString('\n')
	for i := 0; i < len(s); i++ {
		if s[i] == '\n' {
			return s[:i]
		}
	}
	return s
}

输入:

def

输出:

map[def:{abc}]

{abc}
英文:

I am trying to add a bunch of values in a map data type and after that trying to print it out. But it is performing strangely. When I am directly calling the map with the key it is giving me the correct output but not giving me any output when I am storing the key in a variable and then calling it. I am not been able to figure it out what is happening and why am I getting this kind of output. Can Somebody help me with the same.

package main

import (
&quot;bufio&quot;
&quot;fmt&quot;
&quot;os&quot;
)
func main(){
type Authentication struct {
	password string
}
var authentication = map[string]Authentication{}

var user1 Authentication
user1.password = &quot;abc&quot;
authentication[&quot;def&quot;] = user1

reader := bufio.NewReader(os.Stdin)
usid := readString(reader)

fmt.Println(authentication)
fmt.Println(authentication[usid])
fmt.Println(authentication[&quot;def&quot;])
}
// Reading input functions
func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString(&#39;\n&#39;)
for i := 0; i &lt; len(s); i++ {
	if s[i] == &#39;\n&#39; {
		return s[:i]
	}
}
return s
}

Input:

def   

Output:

map[def:{abc}]

{abc}

答案1

得分: 1

你在readString函数中尝试了两次做同样的事情。但你只需要将其减少一个字节即可。

func readString(reader *bufio.Reader) string {
	s, _ := reader.ReadString('\n')

	return s[:len(s)-1]
}
英文:

You're trying to do the same thing twice in readString. But all you have to do is to cut it by one byte.

func readString(reader *bufio.Reader) string {
	s, _ := reader.ReadString(&#39;\n&#39;)

	return s[:len(s)-1]
}

答案2

得分: 1

问题中的程序在使用\r\n作为标准输入的行终止符时无法正常工作。该程序会删除行末尾的\n,但不会删除\r

修复方法是使用bufio.Scanner代替bufio.Reader从输入中读取行。bufio.Scanner类型会删除行终止符。

func main() {
    type Authentication struct {
        password string
    }
    var authentication = map[string]Authentication{}

    var user1 Authentication
    user1.password = "abc"
    authentication["def"] = user1

    scanner := bufio.NewScanner(os.Stdin)
    if !scanner.Scan() {
        log.Fatal(scanner.Err())
    }
    usid := scanner.Text()

    fmt.Println(authentication)
    fmt.Println(authentication[usid])
    fmt.Println(authentication["def"])
}
英文:

The program in the question does not work when \r\n is used as the line terminator in stdin. The program removes the trailing \n from the line, but not the \r.

Fix by using bufio.Scanner instead of bufio.Reader to read lines from the input. The bufio.Scanner type removes line terminators.

func main() {
	type Authentication struct {
		password string
	}
	var authentication = map[string]Authentication{}

	var user1 Authentication
	user1.password = &quot;abc&quot;
	authentication[&quot;def&quot;] = user1

	scanner := bufio.NewScanner(os.Stdin)
	if !scanner.Scan() {
		log.Fatal(scanner.Err())
	}
	usid := scanner.Text()

	fmt.Println(authentication)
	fmt.Println(authentication[usid])
	fmt.Println(authentication[&quot;def&quot;])
}

答案3

得分: 0

读取字符串的方法可能有更好的方式,但我看到你的代码也可以工作。我在本地运行了它,并得到了预期的输出:

根据你的描述,我猜你正在使用Go Playground或类似的平台。如果是这样的话,问题在于Go Playground不接受标准输入,而你的代码使用了os.Stdin作为输入。当我将你的代码复制到Playground并添加以下代码进行检查时,

fmt.Printf("Length of usid: %d\nusid: %q\n", len(usid), usid)

我看到以下输出:

Length of usid: 0
usid: ""

结论:变量、映射或代码都没有问题,只是标准输入有问题。

英文:

There can always be a better way of reading string, but I see your code works too. I ran it in my local and it gives the expected output:
map数据类型的奇怪表现

From your description, I presume you are using go playground or any such platform. If that is so, the thing is, go playground doesn't take standard input, and your code has reader on os.Stdin. When I copy your code to playground and add the following line to check,

fmt.Printf(&quot;Length of usid: %d\nusid: %q\n&quot;, len(usid), usid)

I see the following output:

Length of usid: 0
usid: &quot;&quot;

Conclusion: There is no issue with variables, map or code, but just the stdin.

huangapple
  • 本文由 发表于 2021年10月16日 12:08:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/69592568.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定