Golang fmt Printf 格式化參數手冊/詳解/說明

 

fmt 包實現了格式化I/O函數,相似於C的 printf 和 scanf. 格式「佔位符」衍生自C,但比C更簡單。golang

fmt 包的官方文檔對Printing和Scanning有很詳細的說明。這裏就直接引用文檔進行說明,同時附上額外的說明或例子,以後再介紹具體的函數使用。安全

如下例子中用到的類型或變量定義:函數

type Website struct {
    Name string
}

// 定義結構體變量
var site = Website{Name:"studygolang"}

1.1. Printing

1.1.1. 佔位符

普通佔位符編碼

佔位符                        說明                        舉例                                        輸出
%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
全部錯誤都始於「%!」,有時緊跟着單個字符(佔位符),並以小括號括住的描述結尾。

1.2. 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 在掃描字符串時會將其中的空格做爲分隔符
標記 # 和 + 沒有實現

在使用 %v 佔位符掃描整數時,可接受友好的進制前綴0(八進制)和0x(十六進制)。

寬度被解釋爲輸入的文本(%5s 意爲最多從輸入中讀取5個 rune 來掃描成字符串),而掃描函數則沒有精度的語法(沒有 %5.2f,只有 %5f)。

當以某種格式進行掃描時,不管在格式中仍是在輸入中,全部非空的連續空白字符 (除換行符外)都等價於單個空格。因爲這種限制,格式字符串文本必須匹配輸入的文本,若是不匹配,掃描過程就會中止,並返回已掃描的實參數。

在全部的掃描參數中,若一個操做數實現了 Scan 方法(即它實現了 Scanner 接口), 該操做數將使用該方法掃描其文本。此外,若已掃描的實參數少於所提供的實參數,就會返回一個錯誤。

全部須要被掃描的實參都必須是基本類型或 Scanner 接口的實現。

注意:Fscan 等函數會從輸入中多讀取一個字符(rune),所以,若是循環調用掃描函數,可能會跳過輸入中的某些數據。通常只有在輸入的數據中沒有空白符時該問題纔會出現。若提供給 Fscan 的讀取器實現了 ReadRune,就會用該方法讀取字符。若此讀取器還實現了 UnreadRune 方法,就會用該方法保存字符,而連續的調用將不會丟失數據。若要爲沒有 ReadRune 和 UnreadRune 方法的讀取器加上這些功能,需使用 bufio.NewReader。

相關文章
相關標籤/搜索