1 / Go передает все по значению.
https://golang.org/ref/spec#Calls
При вызове функции значение и аргументы функции оцениваются в обычном порядке. После того, как они оценены, параметры вызова передаются по значению функции, и вызываемая функция начинает выполнение
Таким образом, чтобы записать значение каждой строковой записи срезов, вы можете использоватьуказатели. В этом примере указатель на значение создается и передается функции. Функция обновляет значение, хранящееся по адресу указателей.
Функция небезопасна для нулевых указателей.
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
имеет еще 4непрочитанные байты во внутренний буфер (https://golang.org/src/bufio/bufio.go#L32).
4 байта "2\n3"+"\n"
(echo
добавляет конечный NL).
Эти четыре байта были считаны со стандартного ввода и сохраненыв bufio.Reader
. Этот буферизованный считыватель и его состояние теряются при выходе из функции.
В следующей строке чтения он выводит 0
непрочитанных байтов, фактически он достиг io.EOF
при os.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)
}