Разница между fmt.Println () и println () в Go

117

Как показано ниже, оба fmt.Println()и println()дают одинаковый результат в Go:Hello world!

Но: чем они отличаются друг от друга?

Фрагмент 1 с использованием fmtпакета;

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello world!")
}

Фрагмент 2, без fmtпакета;

package main

func main() {
    println("Hello world!")
}
YulCheney
источник

Ответы:

98

println- это встроенная функция (во время выполнения), которая в конечном итоге может быть удалена, пока fmtпакет находится в стандартной библиотеке, которая будет сохраняться. См. Спецификацию по этой теме.

Для разработчиков языков удобно иметь пакет printlnбез зависимостей, но лучше использовать fmtпакет или что-то подобное ( logнапример).

Как вы можете видеть в реализации в print(ln)функции не предназначена для даже отдаленно поддерживают различные режимы вывода и в основном инструмент отладки.

Немо
источник
108

Чтобы основываться на ответе Немо:

printlnэто функция, встроенная в язык. Он находится в разделе спецификации начальной загрузки . По ссылке:

Текущие реализации предоставляют несколько встроенных функций, полезных во время начальной загрузки. Эти функции задокументированы для полноты, но не гарантируется, что они останутся на языке. Они не возвращают результат.

Function   Behavior

print      prints all arguments; formatting of arguments is implementation-specific
println    like print but prints spaces between arguments and a newline at the end

Таким образом, они полезны для разработчиков, потому что у них отсутствуют зависимости (встроенные в компилятор), но не в производственном коде. Также важно отметить , что printи println доклад stderr, а неstdout .

Семейство, предоставляемое fmt, однако, построено для использования в производственном коде. Они предсказуемо отчитываются stdout, если не указано иное. Они более универсальны ( fmt.Fprint*могут сообщить любому io.Writer, например os.Stdout, os.Stderrили дажеnet.Conn тип.) И не конкретной реализации.

Большинство пакетов, отвечающих за вывод, имеют fmtв качестве зависимости, например log. Если ваша программа будет выводить что-либо в рабочем состоянии, fmtскорее всего, это именно тот пакет, который вам нужен.

Александр Бауэр
источник
3

Я вижу разницу здесь:

rangeOverIntsAndStrings (1, 5)

func rangeOverIntsAndStrings(args ...interface{}) {
    for _, v := range args {
        println(v)
    }
}

// вывод

(0x108f060,0x10c5358)
(0x108f060,0x10c5360)

против

func rangeOverIntsAndStrings(args ...interface{}) {
    for _, v := range args {
        fmt.Println(v)
    }
}

// вывод

1
5
R вс
источник
1

Что касается разницы, то это пример.

println() печатает указатель на адрес функционального теста.

fmt.Println() печатает адрес функции.

Стивен
источник
11
Я не понимаю, что вы пытаетесь сказать.
Пьеро
0

Интересный пример:

  netpoll git:(develop)  cat test.go
package main

import "fmt"

func main() {
        a := new(struct{})
        b := new(struct{})
        println(a, b, a == b)

        c := new(struct{})
        d := new(struct{})
        fmt.Printf("%v %v %v\n", c, d, c == d)
}
  netpoll git:(develop)  go run test.go       
0xc000074f47 0xc000074f47 false
&{} &{} true
  netpoll git:(develop)  go run -gcflags="-m" test.go
# command-line-arguments
./test.go:12:12: inlining call to fmt.Printf
./test.go:6:10: new(struct {}) does not escape
./test.go:7:10: new(struct {}) does not escape
./test.go:10:10: new(struct {}) escapes to heap
./test.go:11:10: new(struct {}) escapes to heap
./test.go:12:35: c == d escapes to heap
./test.go:12:12: []interface {} literal does not escape
<autogenerated>:1: .this does not escape
0xc000074f47 0xc000074f47 false
&{} &{} true

Это некоторая разница между printlnи fmt.Printf.

g10guang
источник