Go'da fmt.Println () ve println () arasındaki fark


117

Aşağıda gösterilen gibi, her iki fmt.Println()ve println()Go aynı çıktıyı verir:Hello world!

Ancak: birbirlerinden nasıl farklılar?

Snippet 1, fmtpaketi kullanarak ;

package main

import (
    "fmt"
)

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

Snippet 2, fmtpaket olmadan ;

package main

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

Yanıtlar:


98

printlnfmtpaket standart kitaplık içindeyken sonunda kaldırılabilen yerleşik bir işlevdir (çalışma zamanına) . O konuyla ilgili spesifikasyona bakın .

Dil geliştiricileri için printlnbağımlılıkların olmaması kullanışlıdır , ancak gitmenin yolu fmtpaketi veya benzer bir şeyi kullanmaktır ( logörneğin).

Eğer gibi uygulanmasında bkzprint(ln) fonksiyonları uzaktan dahi farklı bir çıkış modunu desteklemek üzere tasarlanmış ve esas olarak bir hata ayıklama aracıdır değildir.


108

Nemo'nun cevabına dayanmak için:

printlndilde yerleşik bir işlevdir. Spesifikasyonun Bootstrapping bölümündedir . Bağlantıdan:

Mevcut uygulamalar, önyükleme sırasında yararlı olan çeşitli yerleşik işlevler sağlar. Bu işlevlerin eksiksiz olduğu belgelenmiştir ancak dilde kalmaları garanti edilmez. Sonuç döndürmezler.

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

Bu nedenle, geliştiriciler için yararlıdırlar çünkü bağımlılıkları yoktur (derleyicide yerleşiktirler), ancak üretim kodunda yoktur. Bunu not etmek printve println bildirmekstderrstdout de önemlidir , değil .

fmtBununla birlikte, tarafından sağlanan aile , üretim kodunda olacak şekilde inşa edilmiştir. stdoutAksi belirtilmedikçe, tahmin edilebilir şekilde rapor ederler . Bunlar daha çok yönlü (edilmektedir fmt.Fprint*birine bildirebilirsiniz io.Writergibi os.Stdout, os.Stderrhatta bir net.Conn. Tipi) ve uygulama özgü değildir.

Çıktıdan sorumlu çoğu paketin fmtbağımlılığı vardır, örneğin log. Programınız üretimde herhangi bir çıktı üretecekse fmt, büyük olasılıkla istediğiniz pakettir.


3

Burada farkı görebiliyorum:

rangeOverIntsAndStrings (1, 5)

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

// çıktı

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

vs

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

// çıktı

1
5

1

Farka gelince, bu bir örnek.

println() fonksiyon testinin adresine bir işaretçi gösterir.

fmt.Println() işlevin adresini yazdırır.


11
Ne söylemeye çalıştığını anlamadım.
Pierrot

0

İlginç Örnek:

  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

Bu printlnve arasındaki bir farktır fmt.Printf.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.