官方英文: https://golang.org/pkg/fmt/golang
【簡介】安全
fmt 包實現了格式化 I/O 函數,相似於 C 的 printf 和 scanf。格式「佔位符」衍生自 C,但比 C 更簡單。函數
【打印】編碼
佔位符:指針
[通常]code
%v 相應值的默認格式。在打印結構體時,「加號」標記(%+v)會添加字段名orm
%#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 無小數部分的,指數爲二的冪的科學計數法,與 strconv.FormatFloat 的 'b' 轉換格式一致。例如 -123456p-78
%e 科學計數法,例如 -1234.456e+78
%E 科學計數法,例如 -1234.456E+78
%f 有小數點而無指數,例如 123.456
%g 根據狀況選擇 %e 或 %f 以產生更緊湊的(無末尾的 0)輸出
%G 根據狀況選擇 %E 或 %f 以產生更緊湊的(無末尾的 0)輸出
[字符串與字節切片]
%s 字符串或切片的無解譯字節
%q 雙引號圍繞的字符串,由 Go 語法安全地轉義
%x 十六進制,小寫字母,每字節兩個字符
%X 十六進制,大寫字母,每字節兩個字符
[指針]
%p 十六進制表示,前綴 0x
[注意]
這裏沒有 'u' 標記。若整數爲無符號類型,他們就會被打印成無符號的。相似地, 這裏也不須要指定操做數的大小(int8,int64)。
寬度與精度的控制格式以 Unicode 碼點爲單位。(這點與 C 的 printf 不一樣, 它以字節數爲單位。)兩者或其中之一都可用字符 '*' 表示, 此時它們的值會從下一個操做數中獲取,該操做數的類型必須爲 int。
// 寬度與精度的控制以 Unicode 碼點爲單位 fmt.Printf(""%8s"\n", "123456") // 最大長度爲 8 // " 123456" fmt.Printf(""%8s"\n", "你好") // 最大長度爲 8 // " 你好"
// 寬度與精度都可用字符 '' 表示 fmt.Printf("%0.*f \n", 8, 3, 13.25) // 總長度 8,小數位數 3 fmt.Printf("%08.3f \n", 13.25) // 總長度 8,小數位數 3 // 0013.250
對數值而言,寬度爲該數值佔用區域的最小寬度;精度爲小數點以後的位數。 但對於 %g/%G 而言,精度爲全部數字的總數。例如,對於 123.45,格式 %6.2f 會打印 123.45,而 %.4g 會打印 123.5。%e 和 %f 的默認精度爲 6;但對於 %g 而言,它的默認精度爲肯定該值所必須的最小位數。
對大多數值而言,寬度爲輸出的最小字符數,若是必要的話會爲已格式化的形式填充空格。對字符串而言,精度爲輸出的最大字符數,若是必要的話會直接截斷。
// 寬度與精度標記字符串 fmt.Printf("%8q", "ABC") // 最小長度爲 8(包括 %q 的引號字符) // "ABC" fmt.Printf("%.8q", "1234567890") // 最大長度爲 8(不包括 %q 的引號字符) // "12345678"
[其它標記]
+ 總打印數值的正負號;對於 %q(%+q)保證只輸出 ASCII 編碼的字符。
- 在右側而非左側填充空格(左對齊該區域)
# 備用格式:爲八進制添加前導 0(%#o),爲十六進制添加前導 0x(%#x)或
0X(%#X),爲 %p(%#p)去掉前導 0x;若是可能的話,%q(%#q)會打印原始(即反引號圍繞的)字符串;若是是可打印字符,%U(%#U)會寫出該字符的 Unicode 編碼形式(如字符 x 會被打印成 U+0078 'x')。
' ' (空格)爲數值中省略的正負號留出空白(% d);以十六進制(% x, % X)打印字符串或切片時,在字節之間用空格隔開:
fmt.Printf("% x\n", "Hello") // 48 65 6c 6c 6f
0 填充前導的 0 而非空格;對於數字,這會將填充移到正負號以後
[注意]
標記有時會被佔位符忽略,因此不要期望它們。例如十進制沒有備用格式,所以 %#d 與 %d 的行爲相同。
對於每個 Printf 類的函數,都有一個 Print 函數,該函數不接受任何格式化, 它等價於對每個操做數都應用 %v。另外一個變參函數 Println 會在操做數之間插入空白, 並在末尾追加一個換行符。
不考慮佔位符的話,若是操做數是接口值,就會使用其內部的具體值,而非接口自己。 所以:
var i interface{} = 23 fmt.Printf("%v\n", i) // 會打印 23
若一個操做數實現了 Formatter 接口,該接口就能更好地用於控制格式化。
若其格式(它對於 Println 等函數是隱式的 %v)對於字符串是有效的(%s %q %v %x %X),如下兩條規則也適用:
一、若一個操做數實現了 error 接口,Error 方法就能將該對象轉換爲字符串,隨後會根據佔位符的須要進行格式化。
二、若一個操做數實現了 String() string 方法,該方法能將該對象轉換爲字符串,隨後會根據佔位符的須要進行格式化。
爲避免如下這類遞歸的狀況:
type X string func (x X) String() string { return Sprintf("<%s>", x) }
須要在遞歸前轉換該值: func (x X) String() string { return Sprintf("<%s>", string(x)) }
[格式化錯誤]
若是給佔位符提供了無效的實參(例如將一個字符串提供給 %d),所生成的字符串會包含該問題的描述,以下例所示:
類型錯誤或佔位符未知:%!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)
寬度或精度不是 int 類型:%!(BADWIDTH)或 %!(BADPREC)
Printf("%*s", 4.5, "hi") // %!(BADWIDTH)hi
Printf("%.*s", 4.5, "hi") // %!(BADPREC)hi
全部錯誤都始於「%!」,有時緊跟着單個字符(佔位符),並以小括號括住的描述結尾。
【掃描】
一組相似的函數經過掃描已格式化的文原本產生值。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 在掃描字符串時會將其中的空格做爲分隔符 標記 # 和 + 沒有實現
在使用 %v 佔位符掃描整數時,可接受友好的進制前綴 0(八進制)和 0x(十六進制)。
寬度被解釋爲輸入的文本(%5s 意爲最多從輸入中讀取 5 個符文來掃描成字符串),而掃描函數則沒有精度的語法(沒有 %5.2f,只有 %5f)。
當以某種格式進行掃描時,不管在格式中仍是在輸入中,全部非空的連續空白字符 (除換行符外)都等價於單個空格。因爲這種限制,格式字符串文本必須匹配輸入的文本,若是不匹配,掃描過程就會中止,並返回已掃描的實參數。
在全部的掃描參數中,若一個操做數實現了 Scan 方法(即它實現了 Scanner 接口),該操做數將使用該方法掃描其文本。此外,若已掃描的實參數少於所提供的實參數,就會返回一個錯誤。
全部須要被掃描的實參都必須是基本類型或實現了 Scanner 接口的類型。
注意:Fscan 等函數會從輸入中多讀取一個字符(符文),所以,若是循環調用掃描函數,可能會跳過輸入中的某些數據。通常只有在輸入的數據中沒有空白符時該問題纔會出現。若提供給 Fscan 的讀取器實現了 ReadRune,就會用該方法讀取字符。若此讀取器還實現了 UnreadRune 方法,就會用該方法保存字符,而連續的調用將不會丟失數據。若要爲沒有 ReadRune 和 UnreadRune 方法的讀取器加上這些功能,需使用 bufio.NewReader。