Golang學(xué)習(xí) - fmt 包

// Print 將參數(shù)列表 a 中的各個(gè)參數(shù)轉(zhuǎn)換為字符串并寫入到標(biāo)準(zhǔn)輸出中已慢。
// 非字符串參數(shù)之間會(huì)添加空格入挣,返回寫入的字節(jié)數(shù)移宅。
func Print(a ...interface{}) (n int, err error)

// Println 功能類似 Print,只不過(guò)最后會(huì)添加一個(gè)換行符泡徙。
// 所有參數(shù)之間會(huì)添加空格橱鹏,返回寫入的字節(jié)數(shù)。
func Println(a ...interface{}) (n int, err error)

// Printf 將參數(shù)列表 a 填寫到格式字符串 format 的占位符中堪藐。
// 填寫后的結(jié)果寫入到標(biāo)準(zhǔn)輸出中莉兰,返回寫入的字節(jié)數(shù)。
func Printf(format string, a ...interface{}) (n int, err error)


// 功能同上面三個(gè)函數(shù)礁竞,只不過(guò)將轉(zhuǎn)換結(jié)果寫入到 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)


// 功能同上面三個(gè)函數(shù),只不過(guò)將轉(zhuǎn)換結(jié)果以字符串形式返回模捂。
func Sprint(a ...interface{}) string
func Sprintln(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string


// 功能同 Sprintf捶朵,只不過(guò)結(jié)果字符串被包裝成了 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%
    // 數(shù)值 160 超出范圍(100)
}

func percent(i ...int) error {
    for _, n := range i {
        if n > 100 {
            return fmt.Errorf("數(shù)值 %d 超出范圍(100)", n)
        }
        fmt.Print(n, "%\n")
    }
    return nil
}

// Formatter 由自定義類型實(shí)現(xiàn)狂男,用于實(shí)現(xiàn)該類型的自定義格式化過(guò)程综看。
// 當(dāng)格式化器需要格式化該類型的變量時(shí),會(huì)調(diào)用其 Format 方法岖食。
type Formatter interface {
// f 用于獲取占位符的旗標(biāo)寓搬、寬度、精度等信息县耽,也用于輸出格式化的結(jié)果
// c 是占位符中的動(dòng)詞
Format(f State, c rune)
}

// 由格式化器(Print 之類的函數(shù))實(shí)現(xiàn)句喷,用于給自定義格式化過(guò)程提供信息
type State interface {
// Formatter 通過(guò) Write 方法將格式化結(jié)果寫入格式化器中,以便輸出兔毙。
Write(b []byte) (ret int, err error)
// Formatter 通過(guò) Width 方法獲取占位符中的寬度信息及其是否被設(shè)置唾琼。
Width() (wid int, ok bool)
// Formatter 通過(guò) Precision 方法獲取占位符中的精度信息及其是否被設(shè)置。
Precision() (prec int, ok bool)
// Formatter 通過(guò) Flag 方法獲取占位符中的旗標(biāo)[+- 0#]是否被設(shè)置澎剥。
Flag(c int) bool
}

// Stringer 由自定義類型實(shí)現(xiàn)锡溯,用于實(shí)現(xiàn)該類型的自定義格式化過(guò)程。
// 當(dāng)格式化器需要輸出該類型的字符串格式時(shí)就會(huì)調(diào)用其 String 方法哑姚。
type Stringer interface {
String() string
}

// Stringer 由自定義類型實(shí)現(xiàn)祭饭,用于實(shí)現(xiàn)該類型的自定義格式化過(guò)程。
// 當(dāng)格式化器需要輸出該類型的 Go 語(yǔ)法字符串(%#v)時(shí)就會(huì)調(diào)用其 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("旗標(biāo):[")
        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 函數(shù)倡蝙,則必須自己處理所有格式,包括 %#v
        if c == 'v' && f.Flag('#') {
            write(u.GoString())
        } else {
            write(u.String())
        }
    default: // 如果使用 Format 函數(shù)绞佩,則必須自己處理默認(rèn)輸出
        write("無(wú)效格式:" + string(c))
    }
}

func main() {
    u := Ustr("Hello World!")
    // "-" 標(biāo)記和 "0" 標(biāo)記不能同時(shí)存在
    fmt.Printf("%-+ 0#8.5m\n", u) // 旗標(biāo):[+- #] | 寬度:8 | 精度:5
    fmt.Printf("%+ 0#8.5M\n", u)  // 旗標(biāo):[+ 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)         // 無(wú)效格式:d
}

// Scan 從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)寺鸥,并將數(shù)據(jù)用空白分割并解析后存入 a 提供
// 的變量中(換行符會(huì)被當(dāng)作空白處理),變量必須以指針傳入品山。
// 當(dāng)讀到 EOF 或所有變量都填寫完畢則停止掃描胆建。
// 返回成功解析的參數(shù)數(shù)量。
func Scan(a ...interface{}) (n int, err error)

// Scanln 和 Scan 類似肘交,只不過(guò)遇到換行符就停止掃描笆载。
func Scanln(a ...interface{}) (n int, err error)

// Scanf 從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù),并根據(jù)格式字符串 format 對(duì)數(shù)據(jù)進(jìn)行解析涯呻,
// 將解析結(jié)果存入?yún)?shù) a 所提供的變量中凉驻,變量必須以指針傳入。
// 輸入端的換行符必須和 format 中的換行符相對(duì)應(yīng)(如果格式字符串中有換行
// 符魄懂,則輸入端必須輸入相應(yīng)的換行符)沿侈。
// 占位符 %c 總是匹配下一個(gè)字符,包括空白市栗,比如空格符缀拭、制表符、換行符填帽。
// 返回成功解析的參數(shù)數(shù)量蛛淋。
func Scanf(format string, a ...interface{}) (n int, err error)

// 功能同上面三個(gè)函數(shù),只不過(guò)從 r 中讀取數(shù)據(jù)篡腌。
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)

// 功能同上面三個(gè)函數(shù)褐荷,只不過(guò)從 str 中讀取數(shù)據(jù)。
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)


// 示例

// 對(duì)于 Scan 而言嘹悼,回車視為空白
func main() {
    a, b, c := "", 0, false
    fmt.Scan(&a, &b, &c)
    fmt.Println(a, b, c)
    // 在終端執(zhí)行后叛甫,輸入 abc 1 回車 true 回車
    // 結(jié)果 abc 1 true
}

// 對(duì)于 Scanln 而言层宫,回車結(jié)束掃描
func main() {
    a, b, c := "", 0, false
    fmt.Scanln(&a, &b, &c)
    fmt.Println(a, b, c)
    // 在終端執(zhí)行后,輸入 abc 1 true 回車
    // 結(jié)果 abc 1 true
}

// 格式字符串可以指定寬度
func main() {
    a, b, c := "", 0, false
    fmt.Scanf("%4s%d%t", &a, &b, &c)
    fmt.Println(a, b, c)
    // 在終端執(zhí)行后其监,輸入 1234567true 回車
    // 結(jié)果 1234 567 true
}

// Scanner 由自定義類型實(shí)現(xiàn)萌腿,用于實(shí)現(xiàn)該類型的自定義掃描過(guò)程。
// 當(dāng)掃描器需要解析該類型的數(shù)據(jù)時(shí)抖苦,會(huì)調(diào)用其 Scan 方法毁菱。
type Scanner interface {
// state 用于獲取占位符中的寬度信息,也用于從掃描器中讀取數(shù)據(jù)進(jìn)行解析锌历。
// verb 是占位符中的動(dòng)詞
Scan(state ScanState, verb rune) error
}

// 由掃描器(Scan 之類的函數(shù))實(shí)現(xiàn)贮庞,用于給自定義掃描過(guò)程提供數(shù)據(jù)和信息。
type ScanState interface {
// ReadRune 從掃描器中讀取一個(gè)字符,如果用在 Scanln 類的掃描器中,
// 則該方法會(huì)在讀到第一個(gè)換行符之后或讀到指定寬度之后返回 EOF拧揽。
// 返回“讀取的字符”和“字符編碼所占用的字節(jié)數(shù)”
ReadRune() (r rune, size int, err error)
// UnreadRune 撤消最后一次的 ReadRune 操作浆兰,
// 使下次的 ReadRune 操作得到與前一次 ReadRune 相同的結(jié)果。
UnreadRune() error
// SkipSpace 為 Scan 方法提供跳過(guò)開頭空白的能力。
// 根據(jù)掃描器的不同(Scan 或 Scanln)決定是否跳過(guò)換行符。
SkipSpace()
// Token 用于從掃描器中讀取符合要求的字符串,
// Token 從掃描器中讀取連續(xù)的符合 f(c) 的字符 c伏伐,準(zhǔn)備解析。
// 如果 f 為 nil晕拆,則使用 !unicode.IsSpace(c) 代替 f(c)藐翎。
// skipSpace:是否跳過(guò)開頭的連續(xù)空白。返回讀取到的數(shù)據(jù)实幕。
// 注意:token 指向共享的數(shù)據(jù)吝镣,下次的 Token 操作可能會(huì)覆蓋本次的結(jié)果。
Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
// Width 返回占位符中的寬度值以及寬度值是否被設(shè)置
Width() (wid int, ok bool)
// 因?yàn)樯厦鎸?shí)現(xiàn)了 ReadRune 方法昆庇,所以 Read 方法永遠(yuǎn)不應(yīng)該被調(diào)用末贾。
// 一個(gè)好的 ScanState 應(yīng)該讓 Read 直接返回相應(yīng)的錯(cuò)誤信息。
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("無(wú)效格式:%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)
    // 在終端執(zhí)行后整吆,輸入 ABCDEFGabcdefg 回車
    // 結(jié)果:
    // ABC DEFG abc de
    // 4 無(wú)效格式:x
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拱撵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子表蝙,更是在濱河造成了極大的恐慌拴测,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件府蛇,死亡現(xiàn)場(chǎng)離奇詭異集索,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門务荆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)妆距,“玉大人,你說(shuō)我怎么就攤上這事函匕∫愫瘢” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵浦箱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我祠锣,道長(zhǎng)酷窥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任伴网,我火速辦了婚禮蓬推,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澡腾。我一直安慰自己沸伏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布动分。 她就那樣靜靜地躺著毅糟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澜公。 梳的紋絲不亂的頭發(fā)上姆另,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音坟乾,去河邊找鬼迹辐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甚侣,可吹牛的內(nèi)容都是我干的明吩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼殷费,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼印荔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宗兼,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤躏鱼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后殷绍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體染苛,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茶行。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躯概。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖畔师,靈堂內(nèi)的尸體忽然破棺而出娶靡,到底是詐尸還是另有隱情,我是刑警寧澤看锉,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布姿锭,位于F島的核電站,受9級(jí)特大地震影響伯铣,放射性物質(zhì)發(fā)生泄漏呻此。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一腔寡、第九天 我趴在偏房一處隱蔽的房頂上張望焚鲜。 院中可真熱鬧,春花似錦放前、人聲如沸忿磅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)葱她。三九已至,卻和暖如春叽粹,著一層夾襖步出監(jiān)牢的瞬間览效,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工虫几, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锤灿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓辆脸,卻偏偏與公主長(zhǎng)得像但校,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子啡氢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容