【问题标题】:Strange performing of map data type地图数据类型的奇怪表现
【发布时间】:2021-12-04 02:55:05
【问题描述】:

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

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"])
}
// Reading input functions
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}

【问题讨论】:

  • 使用 bufio.Scanner 读取行终止符被修剪的行。

标签: go goland oracle-golden-gate


【解决方案1】:

您尝试在 readString 中执行两次相同的操作。但你所要做的就是将它削减一个字节。

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

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

【讨论】:

  • 请再看一遍问题。
  • 我认为你是正确的,我需要从输入的字符串中删除最后一个字符,但我已经尝试过你正在做的方式,它不起作用。你可以检查一下
  • 发给我一些可重现的东西。上面的操场运行没有问题。
  • @help_seeker 请参阅play.golang.org/p/mitNvUSrQNm 以获取不起作用的输入示例。
【解决方案2】:

\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"])
}

【讨论】:

    【解决方案3】:

    总有更好的读取字符串的方法,但我看到你的代码也有效。我在本地运行它,它给出了预期的输出:

    根据您的描述,我推测您使用的是 go playground 或任何此类平台。如果是这样,那么问题是,go playground 不接受标准输入,并且您的代码在os.Stdin 上有阅读器。当我将您的代码复制到 Playground 并添加以下行进行检查时,

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

    我看到以下输出:

    Length of usid: 0
    usid: ""
    

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

    【讨论】:

    • 请参阅this program on the playground,其中 stdin 具有 Windows 上典型的 \r\n 行终止符。程序没有正确处理输入。
    • @CeriseLimón 我不确定你是从问题到解决方案,还是倒退。如果您已经知道 Windows 使用 CRLF (\r\n),即 2 个字符,请在您的 if 语句 if s[i] == '\n' || s[i] == '\r' {return s[:i]} 中过滤两者
    • 让我更明确地表达我的观点。您认为 OP 的代码没有问题的结论是不正确的。 OP 的代码不处理 \r\n 行终止符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-08
    • 2017-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2022-01-14
    • 2011-12-21
    相关资源
    最近更新 更多