fmt 包實現了格式化I/O函數,相似於C的 printf 和 scanf. 格式「佔位符」衍生自C,但比C更簡單。golang
fmt 包的官方文檔對Printing和Scanning有很詳細的說明。這裏就直接引用文檔進行說明,同時附上額外的說明或例子,以後再介紹具體的函數使用。安全
如下例子中用到的類型或變量定義:函數
type Website struct { Name string } // 定義結構體變量 var site = Website{Name:"studygolang"}
普通佔位符編碼
佔位符 說明 舉例 輸出 %v 相應值的默認格式。 Printf("%v", site),Printf("%+v", site) {studygolang},{Name:studygolang} 在打印結構體時,「加號」標記(%+v)會添加字段名 %#v 相應值的Go語法表示 Printf("#v", site) main.Website{Name:"studygolang"} %T 相應值的類型的Go語法表示 Printf("%T", site) main.Website %% 字面上的百分號,並不是值的佔位符 Printf("%%") %
布爾佔位符spa
佔位符 說明 舉例 輸出 %t 單詞 true 或 false。 Printf("%t", true) true
整數佔位符指針
佔位符 說明 舉例 輸出 %b 二進制表示 Printf("%b", 5) 101 %c 相應Unicode碼點所表示的字符 Printf("%c", 0x4E2D) 中 %d 十進制表示 Printf("%d", 0x12) 18 %o 八進制表示 Printf("%d", 10) 12 %q 單引號圍繞的字符字面值,由Go語法安全地轉義 Printf("%q", 0x4E2D) '中' %x 十六進制表示,字母形式爲小寫 a-f Printf("%x", 13) d %X 十六進制表示,字母形式爲大寫 A-F Printf("%x", 13) D %U Unicode格式:U+1234,等同於 "U+%04X" Printf("%U", 0x4E2D) U+4E2D
浮點數和複數的組成部分(實部和虛部)code
佔位符 說明 舉例 輸出 %b 無小數部分的,指數爲二的冪的科學計數法,與 strconv.FormatFloat 的 'b' 轉換格式一致。例如 -123456p-78 %e 科學計數法,例如 -1234.456e+78 Printf("%e", 10.2) 1.020000e+01 %E 科學計數法,例如 -1234.456E+78 Printf("%e", 10.2) 1.020000E+01 %f 有小數點而無指數,例如 123.456 Printf("%f", 10.2) 10.200000 %g 根據狀況選擇 %e 或 %f 以產生更緊湊的(無末尾的0)輸出 Printf("%g", 10.20) 10.2 %G 根據狀況選擇 %E 或 %f 以產生更緊湊的(無末尾的0)輸出 Printf("%G", 10.20+2i) (10.2+2i)
字符串與字節切片orm
佔位符 說明 舉例 輸出 %s 輸出字符串表示(string類型或[]byte) Printf("%s", []byte("Go語言中文網")) Go語言中文網 %q 雙引號圍繞的字符串,由Go語法安全地轉義 Printf("%q", "Go語言中文網") "Go語言中文網" %x 十六進制,小寫字母,每字節兩個字符 Printf("%x", "golang") 676f6c616e67 %X 十六進制,大寫字母,每字節兩個字符 Printf("%X", "golang") 676F6C616E67
指針對象
佔位符 說明 舉例 輸出 %p 十六進制表示,前綴 0x Printf("%p", &site) 0x4f57f0
這裏沒有 'u' 標記。若整數爲無符號類型,他們就會被打印成無符號的。相似地,這裏也不須要指定操做數的大小(int8,int64)。blog
寬度與精度的控制格式以Unicode碼點爲單位。(這點與C的 printf 不一樣,它以字節數爲單位)兩者或其中之一都可用字符 '*' 表示,此時它們的值會從下一個操做數中獲取,該操做數的類型必須爲 int。
對數值而言,寬度爲該數值佔用區域的最小寬度;精度爲小數點以後的位數。 但對於 %g/%G 而言,精度爲全部數字的總數。例如,對於123.45,格式 %6.2f 會打印123.45,而 %.4g 會打印123.5。%e 和 %f 的默認精度爲6;但對於 %g 而言,它的默認精度爲肯定該值所必須的最小位數。
對大多數的值而言,寬度爲輸出的最小字符數,若是必要的話會爲已格式化的形式填充空格。對字符串而言,精度爲輸出的最大字符數,若是必要的話會直接截斷。
其它標記
佔位符 說明 舉例 輸出 + 總打印數值的正負號;對於%q(%+q)保證只輸出ASCII編碼的字符。 Printf("%+q", "中文") "\u4e2d\u6587" - 在右側而非左側填充空格(左對齊該區域) # 備用格式:爲八進制添加前導 0(%#o),爲十六進制添加前導 0x(%#x)或 Printf("%#U", '中') U+4E2D '中' 0X(%#X),爲 %p(%#p)去掉前導 0x;若是可能的話,%q(%#q)會打印原始 (即反引號圍繞的)字符串;若是是可打印字符,%U(%#U)會寫出該字符的 Unicode 編碼形式(如字符 x 會被打印成 U+0078 'x')。 ' ' (空格)爲數值中省略的正負號留出空白(% d); 以十六進制(% x, % X)打印字符串或切片時,在字節之間用空格隔開 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),如下兩條規則也適用:
1. 若一個操做數實現了 error 接口,Error 方法就能將該對象轉換爲字符串,隨後會根據佔位符的須要進行格式化。 2. 若一個操做數實現了 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個 rune 來掃描成字符串),而掃描函數則沒有精度的語法(沒有 %5.2f,只有 %5f)。
當以某種格式進行掃描時,不管在格式中仍是在輸入中,全部非空的連續空白字符 (除換行符外)都等價於單個空格。因爲這種限制,格式字符串文本必須匹配輸入的文本,若是不匹配,掃描過程就會中止,並返回已掃描的實參數。
在全部的掃描參數中,若一個操做數實現了 Scan 方法(即它實現了 Scanner 接口), 該操做數將使用該方法掃描其文本。此外,若已掃描的實參數少於所提供的實參數,就會返回一個錯誤。
全部須要被掃描的實參都必須是基本類型或 Scanner 接口的實現。
注意:Fscan 等函數會從輸入中多讀取一個字符(rune),所以,若是循環調用掃描函數,可能會跳過輸入中的某些數據。通常只有在輸入的數據中沒有空白符時該問題纔會出現。若提供給 Fscan 的讀取器實現了 ReadRune,就會用該方法讀取字符。若此讀取器還實現了 UnreadRune 方法,就會用該方法保存字符,而連續的調用將不會丟失數據。若要爲沒有 ReadRune 和 UnreadRune 方法的讀取器加上這些功能,需使用 bufio.NewReader。