arrays - 将带有用户输入的 slice 附加到函数中

标签 arrays go slice

运行此代码时, slice 数据不会被用户输入替换。
但是,当删除注释并在没有函数的情况下正常运行代码时, slice 中的数据将被替换。

package main

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

func main() {
    vriendinnen := []string{"vriendin1", "vriendin2", "vriendin3"}
    koken(vriendinnen[0])
    koken(vriendinnen[1])
    koken(vriendinnen[2])

}

func koken(vriendinnen string) {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Wat Zijn de namen van de vriendinnen: ")
    vriendinnen, _ = reader.ReadString('\n')
    // vriendinnen[1], _ = reader.ReadString('\n')
    // vriendinnen[2], _ = reader.ReadString('\n') 
}

这个作品

    vriendinnen := []string{"vriendin1", "vriendin2", "vriendin3"}
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Wat Zijn de namen van de vriendinnen: ")
    vriendinnen[0], _ = reader.ReadString('\n')
    vriendinnen[1], _ = reader.ReadString('\n')
    vriendinnen[2], _ = reader.ReadString('\n')
    fmt.Println(vriendinnen)

最佳答案

1/Go 通过值传递一切。

https://golang.org/ref/spec#Calls

In a function call, the function value and arguments are evaluated in the usual order. After they are evaluated, the parameters of the call are passed by value to the function and the called function begins execution



因此,要写入 slice 的每个字符串条目的值,您可以使用指针。在此示例中,创建了指向该值的指针并将其传递给函数。该函数更新存储在指针地址处的值。

该函数对 nil 指针不安全。
package main

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

func main() {
    vriendinnen := []string{"vriendin1", "vriendin2", "vriendin3"}
    koken(&vriendinnen[0])
    koken(&vriendinnen[1])
    koken(&vriendinnen[2])

    log.Println(vriendinnen)
}

func koken(vriendinnen *string) {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Wat Zijn de namen van de vriendinnen: ")
    *vriendinnen, _ = reader.ReadString('\n')
    // vriendinnen[1], _ = reader.ReadString('\n')
    // vriendinnen[2], _ = reader.ReadString('\n')
    // reader.WriteTo(w)
}

2/bufio.Reader 被缓冲,因此未能正确管理它可能会导致数据丢失。

这个版本的程序打印了更多细节
package main

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

func main() {
    vriendinnen := []string{"vriendin1", "vriendin2", "vriendin3"}
    koken(&vriendinnen[0])
    koken(&vriendinnen[1])
    koken(&vriendinnen[2])
    log.Println(vriendinnen)
}

func koken(vriendinnen *string) {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Wat Zijn de namen van de vriendinnen: ")
    *vriendinnen, _ = reader.ReadString('\n')
    fmt.Println()
    log.Println(reader.Buffered())
    reader.WriteTo(os.Stdout)
}

使用 echo -e "1\n2\n3" | go run main.go 运行它,它输出
Wat Zijn de namen van de vriendinnen: 
2019/10/07 13:36:53 4
2
3
Wat Zijn de namen van de vriendinnen: 
2019/10/07 13:36:53 0
Wat Zijn de namen van de vriendinnen: 
2019/10/07 13:36:53 0
2019/10/07 13:36:53 [1
  ]

第一行读到 bufio.Reader实例在其内部缓冲区 ( https://golang.org/src/bufio/bufio.go#L32 ) 中仍有 4 个未读字节。

这4个字节是"2\n3"+"\n" (echo 添加尾随 NL)。

这四个字节已从标准输入读取并保存到 bufio.Reader .当函数退出时,这个缓冲的读取器及其状态会丢失。

在下一个读取行,它输出 0未读字节,实际上已经达到io.EOFos.Stdin并且没有其他要阅读的内容。

要解决此问题,请调整您的代码以重用 bufio.Reader .

此外,应注意正确处理错误,以便正确处理 io.EOF .
package main

import (
    "bufio"
    "fmt"
    "io"
    "log"
    "os"
)

func main() {

    vriendinnen := []string{"vriendin1", "vriendin2", "vriendin3"}
    reader := bufio.NewReader(os.Stdin)
    var err error
    for i := 0; i < len(vriendinnen); i++ {
        fmt.Print("Wat Zijn de namen van de vriendinnen: ")
        vriendinnen[i], err = reader.ReadString('\n')
        if err != nil {
            if err == io.EOF {
                err = nil
            }
            break
        }
    }
    if err != nil {
        log.Fatal(err)
    }
    log.Println(vriendinnen)
}

关于arrays - 将带有用户输入的 slice 附加到函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58267463/

相关文章:

string - 如何使用 unsafe 从没有内存复制的字符串中获取字节 slice

arrays - 如何复制或引用一片字节?

java - 如何调整我的 toString 方法以处理多个输入

go - 如何将其他程序包中定义的标志合并到cobra.flags中?

java - 如何初始化一个静态数组?

go - 是否有任何标准库可以将 float64 转换为具有固定宽度和最大有效位数的字符串?

json - 解码 json http 响应

python - 对 pandas 数据框中每个时间序列的第一次出现之前和最后一次出现之后的 NaN 值进行切片

javascript - 获取 Handlebars 中父数组的索引

ios - 从 JSON 响应对象中获取值