91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

格式化輸出(fmt包)

發布時間:2020-06-15 16:09:06 來源:網絡 閱讀:928 作者:騎士救兵 欄目:編程語言

fmt 包

功能:fmt包實現了類似C語言printf和scanf的格式化I/O。格式化動作('verb')源自C語言但更簡單。

fmt格式化輸出

Printf 函數有超過10個各種轉義字符,Go 程序員稱為 verb。下表不完整,但是它說明了很多可用的功能:

verb 描述
%d 十進制數
%x, %o, %b 十六進制,八進制,二進制數
%f, %g, %e 浮點數
%t 布爾型
%c 字符(Unicode碼點)
%s 字符串
%q 帶引號字符串或者字符
%v 內置格式的任何值
%T 任何值的類型
%% 百分號本身

以ln結尾的,比如fmt.Println,使用%v的方式來格式化參數,并且在最后追加換行符。

更詳細的占位符說明

上面的表格比較概括,而且也不全,對于不同的類型,還有不同的細節。所有的說明都在fmt包的doc.go文檔里有詳細的說明:http://docscn.studygolang.com/src/fmt/doc.go

普通占位符

占位符 說明 舉例 輸出
%v 相應值的默認格式。 Printf("%v", people) {zhangsan}
%+v 打印結構體時,會添加字段名 Printf("%+v", people) {Name:zhangsan}
%#v 相應值的Go語法表示 Printf("%#v", people) main.Human{Name:"zhangsan"}
%T 相應值的類型的Go語法表示 Printf("%T", people) main.Human
%% 字面上的百分號,并非值的占位符 Printf("%%") %

布爾占位符

占位符 說明 舉例 輸出
%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格式,相當于 "%04X" 加上前導 "U+" Printf("%U", 0x4E2D) U+4E2D

浮點數和復數

占位符 說明 舉例 輸出
%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)

指針

占位符 說明 舉例 輸出
%p 十六進制表示,前綴 0x Printf("%p", &people) 0x4f57f0

其他標記(副詞)

  • "+" : 總打印數值的正負號;對于%q(%+q)保證只輸出字符的編碼。fmt.Printf("%q %+[1]q\n", "中文") // "中文" "\u4e2d\u6587"
  • "-" : 在右側而非左側填充空格(左對齊該區域)
  • " " : (空格)為數值中省略的正負號留出空白(% d); 以十六進制(% x, % X)打印字符串或切片時,在字節之間用空格隔開
  • "0" : 填充前導的0而非空格;對于數字,這會將填充移到正負號之后
  • "#" : 備用格式,不同的類型還不一樣。
  • "*" : 使用一個變量來控制輸出的寬度,實現可變寬度。

副詞#的備用格式:
八進制、十六進制,默認沒有前導,使用#后會添加前導符號"0"、"0x"、"0X",防止產生歧義:

fmt.Printf("%o %#[1]o\n", 123)        // 173 0173
fmt.Printf("%x %#[1]x %#[1]X\n", 123) // 7b 0x7b 0X7B

指針默認有前導,備用格式就是就掉前導:

var s string
fmt.Printf("%p %#[1]p\n", &s) // 0xc00004c240 c00004c240

對于字符串,%#q有些情況下會輸出反引號圍繞的字符串,不過測試下來不總是這樣:

fmt.Printf("%q, %#[1]q\n", "ab\tcd") // "ab\tcd", `ab   cd`
fmt.Printf("%q, %#[1]q\n", "ab\ncd") // "ab\ncd", "ab\ncd"

對于Unicode,打印出字符的編碼后還會打印該字符:

fmt.Printf("%U, %#[1]U", '中') // U+4E2D, U+4E2D '中'

使用示例

下面是一些可以通過合理的構造格式化字符串來打到最佳的顯示效果的示例。
可能有些示例之間會有點重復。還有一些示例因為太簡單,感覺上一節已經講過了。不過上一節的介紹偏理論,而這里的內容更注重實際使用。

fmt的兩個技巧

一、%后的副詞[1]告知Printf重復使用第一個操作數。
二、%o、%x、%X之前的副詞#告知Printf輸出相應的前綴 0、0x、0X。

func main() {
    o := 0666
    fmt.Printf("%d %[1]o %#[1]o\n", o)  // 438 666 0666
    x := int64(0xdeadbeef)
    fmt.Printf("%d %[1]x %#[1]x %#[1]X\n", x)  // 3735928559 deadbeef 0xdeadbeef 0XDEADBEEF
}

輸出字節序列

使用%x可以輸出字節序列的UTF-8編碼,還可以加上空格也就是% x,這樣每個字符還能隔開,在對字節序列進行輸出的時候特別有用:

fmt.Printf("%x\n", "abcdefg")   // "61626364656667"
fmt.Printf("% x\n", "abcdefg")  // "61 62 63 64 65 66 67"
fmt.Printf("% #x\n", "abcdefg") // "0x61 0x62 0x63 0x64 0x65 0x66 0x67"

對于Unicode字符,還是按照字節處理的,如若要輸出Unicode碼點,需要先轉成[]rune類型:

fmt.Printf("% x\n", "世界")        // "e4 b8 96 e7 95 8c"
fmt.Printf("%x\n", []rune("世界")) // "[4e16 754c]"

指定寬度

通過指定相同的寬度,可以做到右對齊的效果:

func main() {
    fmt.Printf("%4d\n", 1)
    fmt.Printf("%4d\n", 10)
    fmt.Printf("%4d\n", 100)
    fmt.Printf("%4d\n", 1000)
    fmt.Printf("%4d\n", 10000)  // 這個會超出寬度
}

/* 輸出結果
$ go run main.go
   1
  10
 100
1000
10000
*/

這里的頁面似乎看不出對齊的效果,可能是空格的寬度不太一樣。下面使用0填充的對齊效果就有了
如果寬度不夠,輸出時也不會丟失信息,而是把信息全部輸出,不受寬度的限制。
默認使用空格填充,也可以指定填充的內容,比如使用0填充,在輸出二進制數的時候非常有用:

func main() {
    fmt.Printf("%04b\n", 1)
    fmt.Printf("%04b\n", 2)
    fmt.Printf("%04b\n", 3)
    fmt.Printf("%04b\n", 4)
    fmt.Printf("%04b\n", 666)  // 這個會超出寬度
}

/* 輸出結果
$ go run main.go
0001
0010
0011
0100
1010011010
*/

寬度和精度

操作數字的時候,寬度為該數值占用區域的最小寬度;精度為小數點之后的位數。
對于 %g 和 %G 精度是所有數字的總和,而用 %f 打印出來同樣是小數,精度是小數點后面的位數。比如:123.45,%.4g 是 "123.5" 而 %.2f 是 "123.45"。

const n float64 = 123.45
fmt.Printf("%.4g %.2[1]f", n) // g:123.5 f:123.45

打印結構體

打印結構體的時候,使用副詞#或者+可以使結構化符號%v以類似Go語法的方式輸出對象,這個方法里面包含了成員變量的名字:

package main

import "fmt"

// 這可以表示一個坐標
type Point struct {
    X, Y int
}

// 坐標加上半徑就是一個圓
type Circle struct {
    Point
    Radius int
}

// 圓加上輻條數,這表示一個輪子
type Wheel struct {
    Circle
    Spokes int
}

var w Wheel

func main() {
    w = Wheel{Circle{Point{8, 8}, 5}, 20}
    w = Wheel{
        Circle: Circle{
            Point:  Point{X: 8, Y: 8},
            Radius: 5,
        },
        Spokes: 20,
    }

    fmt.Printf("%v\n", w)
    fmt.Printf("%#v\n", w)
}

/* 執行結果
PS H:\Go\src\gopl\ch5\embed> go run main.go
{{{8 8} 5} 20}
main.Wheel{Circle:main.Circle{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
PS H:\Go\src\gopl\ch5\embed>
*/

字符串對齊

寬度和精度對于字符串輸出同樣有效:

  • 寬度為輸出的最小字符數,如果必要的話會為已格式化的形式填充空格。
  • 精度為輸出的最大字符數,如果必要的話會直接截斷。

這樣就可以在輸出字符串的時候做到左對齊和右對齊,輸出類似表格的樣式:

package main

import "fmt"

type message struct {
    Title string
    text  string
}

func main() {
    list := []message{
        {"fmt", "Package fmt implements formatted I/O with functions analogous to C's printf and scanf. The format 'verbs' are derived from C's but are simpler. "},
        {"bytes", "Package bytes implements functions for the manipulation of byte slices. It is analogous to the facilities of the strings package. "},
        {"time", "Package time provides functionality for measuring and displaying time. "},
        {"net/http", "Package http provides HTTP client and server implementations. "},
    }
    _ = list
    for _, msg := range list {
        fmt.Printf("%9.9s %.99s\n", msg.Title, msg.text)
    }
}

/* 輸出效果
PS H:\Go\src\gopl\output> go run main.go
      fmt Package fmt implements formatted I/O with functions analogous to C's printf and scanf. The format '
    bytes Package bytes implements functions for the manipulation of byte slices. It is analogous to the faci
     time Package time provides functionality for measuring and displaying time.
 net/http Package http provides HTTP client and server implementations.
PS H:\Go\src\gopl\output>
*/

不過對于中文輸出就不會那么漂亮了,因為這里填充的空格是半角的空格。

左對齊
其實只要用上制表符\t就能對齊了,不過如果字符串的長度相差比較大,也無法對齊,并且間隔是自動的。下面是另一種精確的實現方法。
默認是在前面進行填充,似乎也沒有在后面填充的格式。不過可以用下面的方法輸出左對齊的效果:

fmt.Printf("%s%*s %.99s\n", msg.Title, 10-len(msg.Title), "", msg.text)

這里的%*s是在s對應的內容輸出前,動態的填充由變量指定的前導空格。由于這里s對應的是空字符串,所以就相當于是動態添加空格,而空格的數量是可以根據前一個變量的長度計算后動態變化的。這是下一節的內容,不過這里正好先展示下效果。

動態控制寬度(縮進)

還有一種控制寬度的方法,使用*號,這種方式輸出的寬度是由之后的變量決定的所以是可變的:

func main() {
    for i := 0; i < 3; i++ {
        fmt.Printf("%*d\n", i*4, i)
    }
}

/* 執行結果
PS H:\Go\src\gopl\output> go run main.go
0
   1
       2
PS H:\Go\src\gopl\output> go run main.go
*/

輸出的寬度由第一個變量控制,而輸出的內容是第二個變量。
這里加了個0,這樣就用0來代替原來的空格來填補寬度了,下面顯示的效果更加直觀:

func main() {
    for i := 0; i < 3; i++ {
        fmt.Printf("%0*d\n", i*4, i)
    }
}

/* 執行結果
PS H:\Go\src\gopl\output> go run main.go
0
0001
00000002
PS H:\Go\src\gopl\output>
*/

由于寬度是包含字符串本身的,而縮進效果是不包括字符串的。所以可是使用空字符串作為第二個參數,把要輸出的內容放在后面。
推薦這么用,fmt.Printf("%*s&lt;%s&gt;\n", n*2, "", "div") 第一個變量控制寬度,第二個是輸出的字符串,這里是空字符串,這里就是兩格縮進的效果。把要輸出的內容放在后面,這里的第三個變量。
這種顯示效果在處理代碼和html標簽的時候特別好,下面的程序先通過Get請求獲取一個頁面,然后解析頁面中的文檔樹,并輸出有縮進效果的樹結構:

package main

import (
    "fmt"
    "net/http"
    "os"

    "golang.org/x/net/html"
)

func main() {
    for _, url := range os.Args[1:] {
        outline(url)
    }
}

func outline(url string) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    doc, err := html.Parse(resp.Body)
    if err != nil {
        return err
    }

    forEachNode(doc, startElement, endElement)
    return nil
}

// 調用 pre(x) 和 post(x) 遍歷以n為根的樹中的每個節點x
// 兩個函數都是可選的
// pre 在子節點被訪問前調用(前序調用)
// post  在訪問后調用(后續調用)
func forEachNode(n *html.Node, pre, post func(n *html.Node)) {
    if pre != nil {
        pre(n)
    }
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        forEachNode(c, pre, post)
    }
    if post != nil {
        post(n)
    }
}

var depth int

func startElement(n *html.Node) {
    if n.Type == html.ElementNode {
        fmt.Printf("%*s<%s>\n", depth*2, "", n.Data)
        depth++
    }
}

func endElement(n *html.Node) {
    if n.Type == html.ElementNode {
        depth--
        fmt.Printf("%*s</%s>\n", depth*2, "", n.Data)
    }
}

/* 執行結果
PS H:\Go\src\gopl\ch6\outline2> go run main.go http://baidu.com
<html>
  <head>
    <meta>
    </meta>
  </head>
  <body>
  </body>
</html>
PS H:\Go\src\gopl\ch6\outline2>
*/
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南皮县| 梨树县| 温宿县| 犍为县| 临安市| 海安县| 花莲县| 东平县| 绥中县| 仁怀市| 柏乡县| 民勤县| 南皮县| 龙泉市| 昭平县| 轮台县| 鹿泉市| 峡江县| 凌云县| 九龙城区| 吉木乃县| 博野县| 来凤县| 通海县| 鲁甸县| 庆阳市| 衡山县| 江西省| 汨罗市| 阿克陶县| 贵南县| 隆昌县| 黄浦区| 广河县| 郧西县| 龙胜| 远安县| 高雄市| 巫山县| 卢湾区| 和平县|