Fmt.Scanln ожидаемая ошибка новой строки

Я пытаюсь изучить Go, но придерживался этого: http://ideone.com/hbCamr или http://ideone.com/OvRw7t

package main
import "fmt"

func main(){
  var i int
  var f float64
  var s string

  _, err := fmt.Scan(&i)
  if err == nil {
    fmt.Println("read 1 integer: ",i)
  } else {
    fmt.Println("Error: ",err)
  }

  _, err = fmt.Scan(&f)
  if err == nil {
    fmt.Println("read 1 float64: ",f)
  } else {
    fmt.Println("Error: ",err)
  }
  _, err = fmt.Scan(&s)
  if err == nil {
    fmt.Println("read 1 string: ",s)
  } else {
    fmt.Println("Error: ",err)
  }

  _, err = fmt.Scanln(&s)
  if err == nil {
    fmt.Println("read 1 line: ",s)
  } else {
    fmt.Println("Error: ",err)
  }
}

для этого ввода:

123
123.456
everybody loves ice cream

вывод был:

read 1 integer:  123
read 1 float64:  123.456
read 1 string:  everybody
Error:  Scan: expected newline

- это ожидаемое поведение? почему он не работает, как С++ getline? http://ideone.com/Wx8z5o

Ответ 1

Ответ находится в документации Scanln:

Scanln похож на Scan, но останавливает сканирование в новой строке, и после последнего элемента должна быть новая строка или EOF.

Scan ведет себя как документально:

Сканирование сканирует текст, считанный со стандартного ввода, сохраняя последовательные значения, разделенные пробелами, в последовательные аргументы. Новые строки считаются пробелом. Он возвращает количество успешно проверенных элементов. Если это меньше, чем число аргументов, err сообщает о том, почему.

В заключение: Scan помещает каждое слово (строку, разделенное пробелом) в соответствующий аргумент, рассматривая новые строки как пробелы. Scanln делает то же самое, но обрабатывает символы новой строки как символ остановки, а затем не разбирается после этого.

Если вы хотите прочитать строку (\n в конце), используйте bufio.Reader и ее метод ReadString:

line, err := buffer.ReadString('\n')