------------------------------------------------------------ // Print 將參數列表 a 中的各個參數轉換爲字符串並寫入到標準輸出中。 // 非字符串參數之間會添加空格,返回寫入的字節數。 func Print(a ...interface{}) (n int, err error) // Println 功能相似 Print,只不過最後會添加一個換行符。 // 全部參數之間會添加空格,返回寫入的字節數。 func Println(a ...interface{}) (n int, err error) // Printf 將參數列表 a 填寫到格式字符串 format 的佔位符中。 // 填寫後的結果寫入到標準輸出中,返回寫入的字節數。 func Printf(format string, a ...interface{}) (n int, err error) ------------------------------ // 功能同上面三個函數,只不過將轉換結果寫入到 w 中。 func Fprint(w io.Writer, a ...interface{}) (n int, err error) func Fprintln(w io.Writer, a ...interface{}) (n int, err error) func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) ------------------------------ // 功能同上面三個函數,只不過將轉換結果以字符串形式返回。 func Sprint(a ...interface{}) string func Sprintln(a ...interface{}) string func Sprintf(format string, a ...interface{}) string ------------------------------ // 功能同 Sprintf,只不過結果字符串被包裝成了 error 類型。 func Errorf(format string, a ...interface{}) error ------------------------------ // 示例 func main() { fmt.Print("a", "b", 1, 2, 3, "c", "d", "\n") fmt.Println("a", "b", 1, 2, 3, "c", "d") fmt.Printf("ab %d %d %d cd\n", 1, 2, 3) // ab1 2 3cd // a b 1 2 3 c d // ab 1 2 3 cd if err := percent(30, 70, 90, 160); err != nil { fmt.Println(err) } // 30% // 70% // 90% // 數值 160 超出範圍(100) } func percent(i ...int) error { for _, n := range i { if n > 100 { return fmt.Errorf("數值 %d 超出範圍(100)", n) } fmt.Print(n, "%\n") } return nil } ------------------------------------------------------------ // Formatter 由自定義類型實現,用於實現該類型的自定義格式化過程。 // 當格式化器須要格式化該類型的變量時,會調用其 Format 方法。 type Formatter interface { // f 用於獲取佔位符的旗標、寬度、精度等信息,也用於輸出格式化的結果 // c 是佔位符中的動詞 Format(f State, c rune) } // 由格式化器(Print 之類的函數)實現,用於給自定義格式化過程提供信息 type State interface { // Formatter 經過 Write 方法將格式化結果寫入格式化器中,以便輸出。 Write(b []byte) (ret int, err error) // Formatter 經過 Width 方法獲取佔位符中的寬度信息及其是否被設置。 Width() (wid int, ok bool) // Formatter 經過 Precision 方法獲取佔位符中的精度信息及其是否被設置。 Precision() (prec int, ok bool) // Formatter 經過 Flag 方法獲取佔位符中的旗標[+- 0#]是否被設置。 Flag(c int) bool } // Stringer 由自定義類型實現,用於實現該類型的自定義格式化過程。 // 當格式化器須要輸出該類型的字符串格式時就會調用其 String 方法。 type Stringer interface { String() string } // Stringer 由自定義類型實現,用於實現該類型的自定義格式化過程。 // 當格式化器須要輸出該類型的 Go 語法字符串(%#v)時就會調用其 String 方法。 type GoStringer interface { GoString() string } ------------------------------ // 示例 type Ustr string func (us Ustr) String() string { return strings.ToUpper(string(us)) } func (us Ustr) GoString() string { return `"` + strings.ToUpper(string(us)) + `"` } func (u Ustr) Format(f fmt.State, c rune) { write := func(s string) { f.Write([]byte(s)) } switch c { case 'm', 'M': write("旗標:[") for s := "+- 0#"; len(s) > 0; s = s[1:] { if f.Flag(int(s[0])) { write(s[:1]) } } write("]") if v, ok := f.Width(); ok { write(" | 寬度:" + strconv.FormatInt(int64(v), 10)) } if v, ok := f.Precision(); ok { write(" | 精度:" + strconv.FormatInt(int64(v), 10)) } case 's', 'v': // 若是使用 Format 函數,則必須本身處理全部格式,包括 %#v if c == 'v' && f.Flag('#') { write(u.GoString()) } else { write(u.String()) } default: // 若是使用 Format 函數,則必須本身處理默認輸出 write("無效格式:" + string(c)) } } func main() { u := Ustr("Hello World!") // "-" 標記和 "0" 標記不能同時存在 fmt.Printf("%-+ 0#8.5m\n", u) // 旗標:[+- #] | 寬度:8 | 精度:5 fmt.Printf("%+ 0#8.5M\n", u) // 旗標:[+ 0#] | 寬度:8 | 精度:5 fmt.Println(u) // HELLO WORLD! fmt.Printf("%s\n", u) // HELLO WORLD! fmt.Printf("%#v\n", u) // "HELLO WORLD!" fmt.Printf("%d\n", u) // 無效格式:d } ------------------------------------------------------------ // Scan 從標準輸入中讀取數據,並將數據用空白分割並解析後存入 a 提供 // 的變量中(換行符會被看成空白處理),變量必須以指針傳入。 // 當讀到 EOF 或全部變量都填寫完畢則中止掃描。 // 返回成功解析的參數數量。 func Scan(a ...interface{}) (n int, err error) // Scanln 和 Scan 相似,只不過遇到換行符就中止掃描。 func Scanln(a ...interface{}) (n int, err error) // Scanf 從標準輸入中讀取數據,並根據格式字符串 format 對數據進行解析, // 將解析結果存入參數 a 所提供的變量中,變量必須以指針傳入。 // 輸入端的換行符必須和 format 中的換行符相對應(若是格式字符串中有換行 // 符,則輸入端必須輸入相應的換行符)。 // 佔位符 %c 老是匹配下一個字符,包括空白,好比空格符、製表符、換行符。 // 返回成功解析的參數數量。 func Scanf(format string, a ...interface{}) (n int, err error) // 功能同上面三個函數,只不過從 r 中讀取數據。 func Fscan(r io.Reader, a ...interface{}) (n int, err error) func Fscanln(r io.Reader, a ...interface{}) (n int, err error) func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) // 功能同上面三個函數,只不過從 str 中讀取數據。 func Sscan(str string, a ...interface{}) (n int, err error) func Sscanln(str string, a ...interface{}) (n int, err error) func Sscanf(str string, format string, a ...interface{}) (n int, err error) ------------------------------ // 示例 // 對於 Scan 而言,回車視爲空白 func main() { a, b, c := "", 0, false fmt.Scan(&a, &b, &c) fmt.Println(a, b, c) // 在終端執行後,輸入 abc 1 回車 true 回車 // 結果 abc 1 true } // 對於 Scanln 而言,回車結束掃描 func main() { a, b, c := "", 0, false fmt.Scanln(&a, &b, &c) fmt.Println(a, b, c) // 在終端執行後,輸入 abc 1 true 回車 // 結果 abc 1 true } // 格式字符串能夠指定寬度 func main() { a, b, c := "", 0, false fmt.Scanf("%4s%d%t", &a, &b, &c) fmt.Println(a, b, c) // 在終端執行後,輸入 1234567true 回車 // 結果 1234 567 true } ------------------------------------------------------------ // Scanner 由自定義類型實現,用於實現該類型的自定義掃描過程。 // 當掃描器須要解析該類型的數據時,會調用其 Scan 方法。 type Scanner interface { // state 用於獲取佔位符中的寬度信息,也用於從掃描器中讀取數據進行解析。 // verb 是佔位符中的動詞 Scan(state ScanState, verb rune) error } // 由掃描器(Scan 之類的函數)實現,用於給自定義掃描過程提供數據和信息。 type ScanState interface { // ReadRune 從掃描器中讀取一個字符,若是用在 Scanln 類的掃描器中, // 則該方法會在讀到第一個換行符以後或讀到指定寬度以後返回 EOF。 // 返回「讀取的字符」和「字符編碼所佔用的字節數」 ReadRune() (r rune, size int, err error) // UnreadRune 撤消最後一次的 ReadRune 操做, // 使下次的 ReadRune 操做獲得與前一次 ReadRune 相同的結果。 UnreadRune() error // SkipSpace 爲 Scan 方法提供跳過開頭空白的能力。 // 根據掃描器的不一樣(Scan 或 Scanln)決定是否跳過換行符。 SkipSpace() // Token 用於從掃描器中讀取符合要求的字符串, // Token 從掃描器中讀取連續的符合 f(c) 的字符 c,準備解析。 // 若是 f 爲 nil,則使用 !unicode.IsSpace(c) 代替 f(c)。 // skipSpace:是否跳過開頭的連續空白。返回讀取到的數據。 // 注意:token 指向共享的數據,下次的 Token 操做可能會覆蓋本次的結果。 Token(skipSpace bool, f func(rune) bool) (token []byte, err error) // Width 返回佔位符中的寬度值以及寬度值是否被設置 Width() (wid int, ok bool) // 由於上面實現了 ReadRune 方法,因此 Read 方法永遠不該該被調用。 // 一個好的 ScanState 應該讓 Read 直接返回相應的錯誤信息。 Read(buf []byte) (n int, err error) } ------------------------------ // 示例 type Ustr string func (u *Ustr) Scan(state fmt.ScanState, verb rune) (err error) { var s []byte switch verb { case 'S': s, err = state.Token(true, func(c rune) bool { return 'A' <= c && c <= 'Z' }) if err != nil { return } case 's', 'v': s, err = state.Token(true, func(c rune) bool { return 'a' <= c && c <= 'z' }) if err != nil { return } default: return fmt.Errorf("無效格式:%c", verb) } *u = Ustr(s) return nil } func main() { var a, b, c, d, e Ustr n, err := fmt.Scanf("%3S%S%3s%2v%x", &a, &b, &c, &d, &e) fmt.Println(a, b, c, d, e) fmt.Println(n, err) // 在終端執行後,輸入 ABCDEFGabcdefg 回車 // 結果: // ABC DEFG abc de // 4 無效格式:x } ------------------------------------------------------------