1. 程式人生 > >GoLang中fmt包的用法

GoLang中fmt包的用法

package fmt

import "fmt"

mt包實現了類似C語言printf和scanf的格式化I/O。格式化verb('verb')源自C語言但更簡單。

Printing

verb:

通用:

%v	值的預設格式表示。當輸出結構體時,擴充套件標誌(%+v)會新增欄位名
%#v	值的Go語法表示
%T	值的型別的Go語法表示
%%	百分號

布林值:

%t	單詞true或false

整數:

%b	表示為二進位制
%c	該值對應的unicode碼值
%d	表示為十進位制
%o	表示為八進位制
%q	該值對應的單引號括起來的go語法字元字面值,必要時會採用安全的轉義表示
%x	表示為十六進位制,使用a-f
%X	表示為十六進位制,使用A-F
%U	表示為Unicode格式:U+1234,等價於"U+%04X"

浮點數、複數的兩個組分:

%b	無小數部分、二進位制指數的科學計數法,如-123456p-78;參見strconv.FormatFloat %e	科學計數法,如-1234.456e+78 %E	科學計數法,如-1234.456E+78 %f	有小數部分但無指數部分,如123.456 %F	等價於%f %g	根據實際情況採用%e或%f格式(以獲得更簡潔、準確的輸出)
%G	根據實際情況採用%E或%F格式(以獲得更簡潔、準確的輸出)

字串和[]byte:

%s	直接輸出字串或者[]byte %q	該值對應的雙引號括起來的go語法字串字面值,必要時會採用安全的轉義表示
%x	每個位元組用兩字元十六進位制數表示(使用a-f)
%X	每個位元組用兩字元十六進位制數表示(使用A-F)

指標:

%p	表示為十六進位制,並加上前導的0x

沒有verb %u。整數如果是無符號型別自然輸出也是無符號的。類似的,也沒有必要指定運算元的尺寸(int8,int64)。

寬度通過一個緊跟在百分號後面的十進位制數指定,如果未指定寬度,則表示值時除必需之外不作填充。精度通過(可能有的)寬度後跟點號後跟的十進位制數指定。如果未指定精度,會使用預設精度;如果點號後沒有跟數字,表示精度為0。舉例如下:

%f:    預設寬度,預設精度
%9f    寬度9,預設精度
%.2f   預設寬度,精度2 %9.2f  寬度9,精度2 %9.f   寬度9,精度0

寬度和精度格式化控制的是Unicode碼值的數量(不同於C的printf,它的這兩個因數指的是位元組的數量)。兩者任一個或兩個都可以使用'*'號取代,此時它們的值將被對應的引數(按'*'號和verb出現的順序,即控制其值的引數會出現在要表示的值前面)控制,這個運算元必須是int型別。

對於大多數型別的值,寬度是輸出的最小字元數,如果必要是會用空格填充。對於字串,寬度是輸出字元數目的最低數量,如果必要會截斷字串。

對於整數,寬度和精度都設定輸出總長度。採用精度時表示右對齊並用0填充,而寬度預設表示用空格填充。

對於浮點數,寬度設定輸出總長度;精度設定小數部分長度(如果有的話),除了%g/%G,此時精度設定總的數字個數。例如,對數字123.45,格式%6.2f 輸出123.45;格式%.4g輸出123.5。%e和%f的預設精度是6,%g的預設精度是可以將該值區分出來需要的最小數字個數。

對複數,寬度和精度會分別用於實部和虛部,結果用小括號包裹。因此%f用於1.2+3.4i輸出(1.200000+3.400000i)。

其它flag:

+	總是輸出數值的正負號;對%q(%+q)會生成全部是ASCII字元的輸出(通過轉義);
-	在輸出右邊填充空白而不是預設的左邊(即從預設的右對齊切換為左對齊);
#	切換格式:
  	八進位制數前加0(%#o),十六進位制數前加0x(%#x)或0X(%#X),指標去掉前面的0x(%#p);
 	對%q(%#q),如果strconv.CanBackquote返回真會輸出反引號括起來的未轉義字串;
 	對%U(%#U),如果字元是可列印的,會在輸出Unicode格式、空格、單引號括起來的go字面值;
' '	對數值,正數前加空格而負數前加負號;
  	對字串採用%x或%X時(% x或% X)會給各列印的位元組之間加空格;
0	使用0而不是空格填充,對於數值型別會把填充的0放在正負號後面;

verb會忽略不支援的flag。例如,因為沒有十進位制切換模式,所以%#d和%d的輸出是相同的。

對每一個類似Printf的函式,都有對應的Print型函式,該函式不接受格式字串,就效果上等價於對每一個引數都是用verb %v。另一個變體Println型函式會在各個運算元的輸出之間加空格並在最後換行。

不管verb如何,如果運算元是一個介面值,那麼會使用介面內部保管的值,而不是介面,因此:

var i interface{} = 23
fmt.Printf("%v\n", i)

會輸出23。

除了verb %T和%p之外;對實現了特定介面的運算元會考慮採用特殊的格式化技巧。按應用優先順序如下:

1. 如果運算元實現了Formatter介面,會呼叫該介面的方法。Formatter提供了格式化的控制。

2. 如果verb %v配合flag #使用(%#v),且運算元實現了GoStringer介面,會呼叫該介面。

如果運算元滿足如下兩條任一條,對於%s、%q、%v、%x、%X五個verb,將考慮:

3. 如果運算元實現了error介面,Error方法會用來生成字串,隨後將按給出的flag(如果有)和verb格式化。

4. 如果運算元具有String方法,這個方法將被用來生成字串,然後將按給出的flag(如果有)和verb格式化。

複合型別的運算元,如切片和結構體,格式化動verb遞迴地應用於其每一個成員,而不是作為整體一個運算元使用。因此%q會將[]string的每一個成員括起來,%6.2f會控制浮點陣列的每一個元素的格式化。

為了避免可能出現的無窮遞迴,如:

type X string
func (x X) String() string { return Sprintf("<%s>", x) }

應在遞迴之前轉換值的型別:

func (x X) String() string { return Sprintf("<%s>", string(x)) }

顯式指定引數索引:

在Printf、Sprintf、Fprintf三個函式中,預設的行為是對每一個格式化verb依次對應呼叫時成功傳遞進來的引數。但是,緊跟在verb之前的[n]符號表示應格式化第n個引數(索引從1開始)。同樣的在'*'之前的[n]符號表示採用第n個引數的值作為寬度或精度。在處理完方括號表示式[n]後,除非另有指示,會接著處理引數n+1,n+2……(就是說移動了當前處理位置)。例如:

fmt.Sprintf("%[2]d %[1]d\n", 11, 22)

會生成"22 11",而:

fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),

等價於:

fmt.Sprintf("%6.2f", 12.0),

會生成" 12.00"。因為顯式的索引會影響隨後的verb,這種符號可以通過重設索引用於多次列印同一個值:

fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)

會生成"16 17 0x10 0x11"

格式化錯誤:

如果給某個verb提供了非法的引數,如給%d提供了一個字串,生成的字串會包含該問題的描述,如下所例:

錯誤的型別或未知的verb:%!verb(type=value)
	Printf("%d", hi):          %!d(string=hi)
太多引數(採用索引時會失效):%!(EXTRA type=value)
	Printf("hi", "guys"):      hi%!(EXTRA string=guys)
太少引數: %!verb(MISSING)
	Printf("hi%d"):            hi %!d(MISSING)
寬度/精度不是整數值:%!(BADWIDTH) or %!(BADPREC)
	Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
	Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
沒有索引指向的引數:%!(BADINDEX)
	Printf("%*[2]d", 7):       %!d(BADINDEX)
	Printf("%.[2]d", 7):       %!d(BADINDEX)

所有的錯誤都以字串"%!"開始,有時會後跟單個字元(verb識別符號),並以加小括弧的描述結束。

如果被print系列函式呼叫時,Error或String方法觸發了panic,fmt包會根據panic重建錯誤資訊,用一個字串說明該panic經過了fmt包。例如,一個String方法呼叫了panic("bad"),生成的格式化資訊差不多是這樣的:

%!s(PANIC=bad)

%!s指示表示錯誤(panic)出現時的使用的verb。

Scanning

一系列類似的函式可以掃描格式化文字以生成值。

Scan、Scanf和Scanln從標準輸入os.Stdin讀取文字;Fscan、Fscanf、Fscanln從指定的io.Reader介面讀取文字;Sscan、Sscanf、Sscanln從一個引數字串讀取文字。

Scanln、Fscanln、Sscanln會在讀取到換行時停止,並要求一次提供一行所有條目;Scanf、Fscanf、Sscanf只有在格式化文字末端有換行時會讀取到換行為止;其他函式會將換行視為空白。

Scanf、Fscanf、Sscanf會根據格式字串解析引數,類似Printf。例如%x會讀取一個十六進位制的整數,%v會按對應值的預設格式讀取。格式規則類似Printf,有如下區別:

%p 未實現
%T 未實現
%e %E %f %F %g %G 效果相同,用於讀取浮點數或複數型別
%s %v 用在字串時會讀取空白分隔的一個片段
flag # 和 + 未實現

在無格式化verb或verb %v下掃描整數時會接受常用的進位制設定字首0(八進位制)和0x(十六進位制)。

寬度會在輸入文字中被使用(%5s表示最多讀取5個rune來生成一個字串),但沒有使用精度的語法(沒有%5.2f,只有%5f)。

當使用格式字串進行掃描時,多個連續的空白字元(除了換行符)在輸出和輸出中都被等價於一個空白符。在此前提下,格式字串中的文字必須匹配輸入的文字;如果不匹配掃描會中止,函式的整數返回值說明已經掃描並填寫的引數個數。

在所有的掃描函式裡,\r\n都被視為\n。

在所有的掃描函式裡,如果一個運算元實現了Scan方法(或者說,它實現了Scanner介面),將會使用該介面為該運算元掃描文字。另外,如果如果掃描到(準備填寫)的引數比提供的引數個數少,會返回一個錯誤。

提供的所有引數必須為指標或者實現了Scanner介面。注意:Fscan等函式可能會在返回前多讀取一個rune,這導致多次呼叫這些函式時可能會跳過部分輸入。只有在輸入裡各值之間沒有空白時,會出現問題。如果提供給Fscan等函式的io.Reader介面實現了ReadRune方法,將使用該方法讀取字元。如果該io.Reader介面還實現了UnreadRune方法,將是使用該方法儲存字元,這樣可以使成功執行的Fscan等函式不會丟失資料。如果要給一個沒有這兩個方法的io.Reader介面提供這兩個方法,使用bufio.NewReader。

Index

type Stringer interface { String() string }

實現了Stringer介面的型別(即有String方法),定義了該型別值的原始顯示。當採用任何接受字元的verb(%v %s %q %x %X)動作格式化一個運算元時,或者被不使用格式字串如Print函式列印運算元時,會呼叫String方法來生成輸出的文字。

type GoStringer interface { GoString() string }

實現了GoStringer介面的型別(即有GoString方法),定義了該型別值的go語法表示。當採用verb %#v格式化一個運算元時,會呼叫GoString方法來生成輸出的文字。

type State

type State interface { // Write方法用來寫入格式化的文字 
    Write(b []byte) (ret int, err error) // Width返回寬度值,及其是否被設定 
    Width() (wid int, ok bool) // Precision返回精度值,及其是否被設定 
    Precision() (prec int, ok bool) // Flag報告是否設定了flag c(一個字元,如+、-、#等)            
    Flag(c int) bool 
}

State代表一個傳遞給自定義Formatter介面的Format方法的列印環境。它實現了io.Writer介面用來寫入格式化的文字,還提供了該運算元的格式字串指定的選項和寬度、精度資訊(通過呼叫方法)。

type Formatter interface { // c為verb,f提供verb的細節資訊和Write方法用於寫入生成的格式化文字 Format(f State, c rune)
}

實現了Formatter介面的型別可以定製自己的格式化輸出。Format方法的實現內部可以呼叫Sprint或Fprint等函式來生成自身的輸出。

type ScanState interface { // 從輸入讀取下一個rune(Unicode碼值),在讀取超過指定寬度時會返回EOF 
                           // 如果在Scanln、Fscanln或Sscanln中被呼叫,本方法會在返回第一個'\n'後再次呼叫時返回EOF 
    ReadRune() (r rune, size int, err error) // UnreadRune方法讓下一次呼叫ReadRune時返回上一次返回的rune且不移動讀取位置 
    UnreadRune() error // SkipSpace方法跳過輸入中的空白,換行被視為空白 // 在Scanln、Fscanln或Sscanln中被呼叫時,換行被視為EOF 
    SkipSpace() // 方法從輸入中依次讀取rune並用f測試,直到f返回假;將讀取的rune組織為一個[]byte切片返回。 // 如果skipSpace引數為真,本方法會先跳過輸入中的空白。 // 如果f為nil,會使用!unicode.IsSpace(c);就是說返回值token將為一串非空字元。 // 換行被視為空白,在Scanln、Fscanln或Sscanln中被呼叫時,換行被視為EOF。 // 返回的切片指向一個共享記憶體,可能被下一次呼叫Token方法時重寫; // 或被使用該Scanstate的另一個Scan函式重寫;或者在本次呼叫的Scan方法返回時重寫。 
    Token(skipSpace bool, f func(rune) bool) (token []byte, err error) // Width返回返回寬度值,及其是否被設定。單位是unicode碼值。 
    Width() (wid int, ok bool) // 因為本介面實現了ReadRune方法,Read方法永遠不應被在Scanner介面中使用。 // 一個合法的ScanStat介面實現可能會選擇讓本方法總是返回錯誤。 
    Read(buf []byte) (n int, err error) 
}

ScanState代表一個將傳遞給Scanner介面的Scan方法的掃描環境。 Scan函式中,可以進行一次一個rune的掃描,或者使用Token方法獲得下一個token(比如空白分隔的token)。

type Scanner interface { Scan(state ScanState, verb rune) error }

當Scan、Scanf、Scanln或類似函式接受實現了Scanner介面的型別(其Scan方法的receiver必須是指標,該方法從輸入讀取該型別值的字串表示並將結果寫入receiver)的指標作為引數時,會呼叫其Scan方法進行定製的掃描。

func Printf(format string, a ...interface{}) (n int, err error)

Printf根據format引數生成格式化的字串並寫入標準輸出。返回寫入的位元組數和遇到的任何錯誤。

func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)

Fprintf根據format引數生成格式化的字串並寫入w。返回寫入的位元組數和遇到的任何錯誤。

func Sprintf(format string, a ...interface{}) string

Sprintf根據format引數生成格式化的字串並返回該字串。

func Print

func Print(a ...interface{}) (n int, err error)

Print採用預設格式將其引數格式化並寫入標準輸出。如果兩個相鄰的引數都不是字串,會在它們的輸出之間新增空格。返回寫入的位元組數和遇到的任何錯誤。

func Fprint(w io.Writer, a ...interface{}) (n int, err error)

Fprint採用預設格式將其引數格式化並寫入w。如果兩個相鄰的引數都不是字串,會在它們的輸出之間新增空格。返回寫入的位元組數和遇到的任何錯誤。

func Sprint(a ...interface{}) string

Sprint採用預設格式將其引數格式化,串聯所有輸出生成並返回一個字串。如果兩個相鄰的引數都不是字串,會在它們的輸出之間新增空格。

func Println(a ...interface{}) (n int, err error)

Println採用預設格式將其引數格式化並寫入標準輸出。總是會在相鄰引數的輸出之間新增空格並在輸出結束後新增換行符。返回寫入的位元組數和遇到的任何錯誤。

func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

Fprintln採用預設格式將其引數格式化並寫入w。總是會在相鄰引數的輸出之間新增空格並在輸出結束後新增換行符。返回寫入的位元組數和遇到的任何錯誤。

func Sprintln(a ...interface{}) string

Sprintln採用預設格式將其引數格式化,串聯所有輸出生成並返回一個字串。總是會在相鄰引數的輸出之間新增空格並在輸出結束後新增換行符。

func Errorf(format string, a ...interface{}) error

Errorf根據format引數生成格式化字串並返回一個包含該字串的錯誤。

func Scanf

func Scanf(format string, a ...interface{}) (n int, err error)

Scanf從標準輸入掃描文字,根據format 引數指定的格式將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。返回成功掃描的條目個數和遇到的任何錯誤。

func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)

Fscanf從r掃描文字,根據format 引數指定的格式將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。返回成功掃描的條目個數和遇到的任何錯誤。

func Sscanf(str string, format string, a ...interface{}) (n int, err error)

Sscanf從字串str掃描文字,根據format 引數指定的格式將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。返回成功掃描的條目個數和遇到的任何錯誤。

func Scan

func Scan(a ...interface{}) (n int, err error)

Scan從標準輸入掃描文字,將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的引數少,會返回一個錯誤報告原因。

func Fscan

func Fscan(r io.Reader, a ...interface{}) (n int, err error)

Fscan從r掃描文字,將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的引數少,會返回一個錯誤報告原因。

func Sscan

func Sscan(str string, a ...interface{}) (n int, err error)

Sscan從字串str掃描文字,將成功讀取的空白分隔的值儲存進成功傳遞給本函式的引數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的引數少,會返回一個錯誤報告原因。

func Scanln(a ...interface{}) (n int, err error)

Scanln類似Scan,但會在換行時才停止掃描。最後一個條目後必須有換行或者到達結束位置。

func Fscanln(r io.Reader, a ...interface{}) (n int, err error)

Fscanln類似Fscan,但會在換行時才停止掃描。最後一個條目後必須有換行或者到達結束位置。

func Sscanln(str string, a ...interface{}) (n int, err error)

Sscanln類似Sscan,但會在換行時才停止掃描。最後一個條目後必須有換行或者到達結束位置。

相關推薦

GoLangfmt用法

package fmt import "fmt" mt包實現了類似C語言printf和scanf的格式化I/O。格式化verb('verb')源自C語言但更簡單。 Printing verb: 通用: %v 值的預設格式表示。當輸出結構體時,擴充套件標誌(%+v)

golang io用法(一)

不同的 下一個 同時 顯示 cte () ews 執行 忽略 本文轉自Golove博客:http://www.cnblogs.com/golove/p/3276678.html io 包為I/O原語提供了基礎的接口.它主要包裝了這些原語的已有實現,如 os 包中的

golang strconv用法

本文轉自Golove部落格:http://www.cnblogs.com/golove/p/3262925.html strconv 包中的函式和方法 // atob.go --------------------------------------------------

golangio用法(二)

io 包為I/O原語提供了基本的介面。它主要包裝了這些原語的已有實現。 由於這些介面和原語以不同的實現包裝了低階操作,因此除非另行通知,否則客戶端不應假定它們對於並行執行是安全的。 在io包中最重要的是兩個介面:Reader和Writer介面。本章所提到的各種IO包,都

golangsort用法

golang中也實現了排序演算法的包sort包. sort包中實現了3種基本的排序演算法:插入排序.快排和堆排序.和其他語言中一樣,這三種方式都是不公開的,他們只在sort包內部使用.所以使用者在使用sort包進行排序時無需考慮使用那種排序方式,sort.Interface

golangimage用法

image包實現了一個基本的2D影象庫,該包中包含基本的介面叫做image,這個裡面包含color,這個將在image/color中描述, image介面的值建立方式有如下幾種: 1呼叫NewRGBA和NewPaletted 2解碼一個包含gif.jpen或者png格式的i

golangtime用法

time包中包括兩類時間:時間點(某一時刻)和時常(某一段時間) 1時間常量(時間格式化) const ( ANSIC = "Mon Jan _2 15:04:05 2006" UnixDate = "Mon Jan _2 15:04:0

golang unicode用法

本文轉自Golove部落格:http://www.cnblogs.com/golove/p/3273585.html unicode 包中的函式和方法 // latters.go const ( MaxRune = '\U0010FFFF' // Unicode 碼點最大值

Go_20: Golang time 的使用

舉例 處理程序 計算表達式 時間格式化 停止 out str div ati time包中包括兩類時間:時間點(某一時刻)和時常(某一段時間) 1. 時間常量(時間格式化) const ( ANSIC = "Mon Jan _2 15:04:05 20

golang sync的 WaitGroup

eight ack family height 線程 var 等待 one span   golang 中的 sync 包有一個很有用的功能,就是 WaitGroup   先說說 WaitGroup 的用途:它能夠一直等到所有的 goroutine 執行完成,並且阻塞主線程

Golangheap原始碼分析

heap的實現使用到了小根堆,下面先對堆做個簡單說明 1. 堆概念     堆是一種經過排序的完全二叉樹,其中任一非終端節點的資料值均不大於(或不小於)其左孩子和右孩子節點的值。   最大堆和最小堆是二叉堆的兩種形式。   最大堆:根結點的鍵值是所有堆結點鍵值中最大者。   最小

golanggorm的操作

1.簡單的連線和CURD package main import ( "github.com/jinzhu/gorm" _ "github.com/go-sql-driver/mysql" "time" ) type User struct { User_id

golangxorm使用map[string]interface{}

前言: 許久沒發個人部落格了,最近有點忙,很是懷念以前有時間寫部落格的日子。最近做各種後臺服務,寫了N個rest介面,其中有相當一部分是和mysql掛鉤的,這時候就使用起了golang的xorm包。特意

golang一些基礎用法

range類似迭代器操作,返回 (索引, 值) 或 (鍵, 值)。其可以使用的物件包括string,array/slice,map,channel。其中string,array/slice返回的第一個value都是index,第二個value表示值;map返回第一個元素為k

golanggoconfig使用解析

注意事項 本博文為 goconfig - Go 語言 INI 解析器的配套部落格,旨在通過文字結合程式碼示例對該庫的使用方法和案例進行講解,便於各位同學更好地使用和深入瞭解。 庫簡介 goconfig 是一個由 Go 語言開發的針對 Windows 下常見的 INI 格式

golangfmtString(),Error(),Format(),GoString()的介面實現

簡介 golang的介面使用非常廣泛,幾乎每一個包都會用到介面,fmt包的使用率最多之一。在實際開發中,要定義結構體的標準輸出用String(),定義標準錯誤輸出Error(),定義格式化輸出Format(),還有比較特殊的GoString()。接下來描述介面的使用方式,使用場景,還有注意的地方。 Str

python json 用法簡單總結

JSON包的引用 在檔案頭部引用json包 import json python物件與JSON物件的互相轉換 json物件的型別為’str’: dic = {'b':'I', 'a':123, 'c':'100'} j1

golangos/exec用法

exec包執行外部命令,它將os.StartProcess進行包裝使得它更容易對映到stdin和stdout,並且利用pipe連線i/o. func LookPath(file string) (string, error) //LookPath在環境變數中查詢科執行二進位

golangarchive/zip用法

archive/zip包提供了zip歸檔檔案的讀寫操作。 在對zip包進行介紹之前,先說明一下zip和tar的區別。 二者都是對檔案進行歸檔,不進行壓縮。並且二者使用平臺不同,對於 Windows 平臺而言,最常用的格式是 zip 和 rar,國內大多數是用 rar,國外大

golangos/user用法

os/user包允許使用者賬號通過使用者名稱或者使用者id查詢使用者 type UnknownUserError type UnknownUserError string func (e UnknownUserError) Error() string  //當通過