Unterschied zwischen fmt.Println () und println () in Go

116

Wie unten dargestellt, geben beide fmt.Println()und println()dieselbe Ausgabe in Go:Hello world!

Aber: Wie unterscheiden sie sich voneinander?

Snippet 1 unter Verwendung des fmtPakets;

package main

import (
    "fmt"
)

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

Snippet 2 ohne das fmtPaket;

package main

func main() {
    println("Hello world!")
}
YulCheney
quelle

Antworten:

98

printlnist eine integrierte Funktion (in der Laufzeit), die möglicherweise entfernt wird, während sich das fmtPaket in der Standardbibliothek befindet, die bestehen bleibt. Siehe die Spezifikation zu diesem Thema.

Für Sprachentwickler ist es praktisch, eine printlnohne Abhängigkeiten zu haben , aber der Weg ist, das fmtPaket oder etwas Ähnliches ( logzum Beispiel) zu verwenden.

Wie Sie in der Implementierung sehen können, unterstützen die print(ln)Funktionen nicht einmal einen anderen Ausgabemodus aus der Ferne und sind hauptsächlich ein Debug-Tool.

nemo
quelle
108

Um auf Nemos Antwort aufzubauen:

printlnist eine in die Sprache eingebaute Funktion. Es befindet sich im Abschnitt Bootstrapping der Spezifikation . Über den Link:

Aktuelle Implementierungen bieten mehrere integrierte Funktionen, die beim Bootstrapping nützlich sind. Diese Funktionen sind der Vollständigkeit halber dokumentiert, es wird jedoch nicht garantiert, dass sie in der Sprache bleiben. Sie geben kein Ergebnis zurück.

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

Daher sind sie für Entwickler nützlich, da ihnen Abhängigkeiten fehlen (die in den Compiler integriert sind), jedoch nicht im Produktionscode. Es ist auch wichtig zu beachten , dass printund println Bericht stderrnichtstdout .

Die von bereitgestellte Familie fmtist jedoch so aufgebaut, dass sie im Produktionscode enthalten ist. Sie berichten vorhersehbar an stdout, sofern nicht anders angegeben. Sie sind vielseitig ( fmt.Fprint*können zu einem Bericht io.Writer, wie os.Stdout, os.Stderroder sogar einnet.Conn Art.) Und sind nicht Umsetzung spezifisch.

Die meisten Pakete, die für die Ausgabe verantwortlich sind, haben fmteine Abhängigkeit, wie z log. Wenn Ihr Programm irgendetwas in der Produktion ausgibt, fmtist es höchstwahrscheinlich das Paket, das Sie wollen.

Alexander Bauer
quelle
3

Ich kann hier einen Unterschied sehen:

rangeOverIntsAndStrings (1, 5)

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

// Ausgabe

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

vs.

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

// Ausgabe

1
5
R Sonne
quelle
1

Wie für den Unterschied, dies ist ein Beispiel.

println() Gibt einen Zeigerpunkt auf die Adresse des Funktionstests aus.

fmt.Println() druckt die Adresse der Funktion.

Steven
quelle
11
Ich verstehe nicht, was Sie sagen wollen.
Pierrot
0

Interessantes Beispiel:

  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

Es ist etwas Unterschied zwischen printlnund fmt.Printf.

g10guang
quelle