go标准库fmt学习

3次阅读

共计 2987 个字符,预计需要花费 8 分钟才能阅读完成。

go 标准库(fmt)学习

每种编程语言都有自己的格式化输入和输出。c 语言是通过标准输入输出库(stdio),python 语言是语言的一部分(print)。go 语言是通过库(fmt)来实现格式化输入输出的功能。

1 打印

1.1 打印格式

格式符号 描述
%v 打印默认格式
%+v 当打印结构体时,会添加字段名
%#v go 语法展示数据
%T go 语法展示数据的类型
%% 打印 %

测试数据:

type Person struct {
    Name string
    age  int
}

var SimpleData = map[string]interface{}{
    "int":     1,
    "string":  "hello",
    "float":   1.23,
    "complex": complex(1, 2),
    "bool": 0 == 0,
}
var ComplexData = map[string]interface{}{"slice": []int{1, 2, 3},
    "map": map[string]int{
        "a": 1,
        "b": 2,
    },
    "struct": Person{"Moon", 33},
}

%v 和 %+ v 打印都是一样的,只有 struct 打印是不同的。

struct        {Moon 33} //%v 打印结构体
struct        {Name:Moon age:33} // %+ v 打印结构体

%#v 的打印

"slice"        []int{1, 2, 3} //go 语法的字符串会添加双引号,slice 是 go 语法定义的模式
"map"        map[string]int{"a":1, "b":2} //map 的打印

%T 打印类型

map        map[string]int //map 的类型
slice        []int//slice 的类型

上面是一般模式的打印,下面我们考虑精确到具体的类型的打印。

  • 如何打印 boolean 类型

    • %t 可以打印 boolean 值,值是 true 或者 false
  • 如何打印 interger

    • 二进制 %b
    • 十进制 %d
    • 八进制 %o
    • 十六进制 %x 或者 %X
    • unicode 格式 %U
    • %c unicode code point
      var IntegerFormat = map[string]string{
          "base10":   "%d",
          "base8":    "%o",
          "base16":   "%x",
          "unicode":  "%U",
          "unicodec": "%c",
      }
    
      base10:42
      base8:52
      base16:2a
      unicode:U+002A
      unicodec:*
  • 如何打印 float

    • 指数形式 2 为底的指数形式 %b,e 为底的指数形式 %e,%E
    • 非指数形式,%f 或者 %F
    • 通用形式 %g,或者 %G 根据实际情况使用 %e 或者 %f

      fmt.Printf("%b\n", SimpleData["float"])
      fmt.Printf("%f\n", SimpleData["float"])
      fmt.Printf("%e\n", SimpleData["float"])
      //Output
      //5539427541665710p-52
      //1.230000
      //1.230000e+00
  • 如何打印 string

    • go 语法形式 %q
    • 普通形式 %s
    • 16 进制模式 %x 或者 %X
    /*
      string normal: hello, world
      string go syntax:"hello, world"
      string normal: good morning
      string go syntax:"good morning"
      string base 16:676f6f64206d6f726e696e67
    */
  • 如何打印 slice

    • 打印首元素的地址 %p
  • 如何打印 point

    • 打印指针地址
fmt.Printf("slice %p\n", ComplexData["slice"])
a := 5
p := &a
fmt.Printf("Point %p\n", p)
//slice 0xc000064140
//Point 0xc000066088

1.2 width precision
duration . 表示 duration
实例最好说明这两个东西,比如 ”%9.2f”, 宽度是 9,精度是 2,我们用实例来展示这两个东西。

fmt.Printf("%f\n", SimpleData["float"])
fmt.Printf("%6.2f\n", SimpleData["float"])
fmt.Printf("%  10f\n", SimpleData["float"])
fmt.Printf("%.5f\n", SimpleData["float"])
/*
Output:
123456789.123457 // 默认的精度是 6
123456789.12
 123456789.123457 //10 的宽度,实际有 11,舍弃一个空隔
123456789.12346 
*/
宽度和精度都是通过 unicode 码点的单位数量来度量的,也就是 rune 个数。其中 "%5.2f" 中的 5 和 2 这种整数类型可以用 * 代替,通过后面的参数传递。```
fmt.Printf("%5.2f", 1.2345)
fmt.Printf("%*.*f", 5, 2, 1.2345)
// 两个的输出都是 1.23
```
  • 大部分的数值的宽度,是能够展示这个数据的最小 runes 加上格式化指定的空格数。
  • 字符串和 byte 切片,精度控制的输入的长度,如果是 %x 使用字节数来度量

    s := "hello, world"
    b := []byte("good morning")
    fmt.Printf("%.4s %.5s\n", s, b)
    //Output: 
    //hell good 
  • 浮点数,width 代表的是整数部分,precision 代表的小数点后的位数
  • 复数,width 和 precision 对实部和虚部都有效

其他标记:

    • 打印符号
    • 右边填充空格
  • ‘#’八进制填充 O,16 进制填充 0x …
  • ‘’填充空格
  • 0 填充 0

Print 默认使用 %v,Pirntln 自动填充空格并且添加换行符。
1.3 接口
传入的操作数是接口,打印的是运行时该变量的值而不是接口本身。

  • 如果操作数是一个 reflect.value,打印将使用它运行时的值
  • 如果传入接口的类型实现了 Formater,它将会被调用。
  • 如果使用 %#v, 类型实现了 GoString 方法,这个将会被调用
  • 如果实现了 error 的 interface,Error 方法将会被调用(需要 string 的 verb)
  • 如果实现了 String 该方法,它将会被调用(需要 string 的 verb)

1.4 显式的位置参数
%[index]verb 通过后面的传入操作数的位置来匹配 verb

fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
// 16 先传给第一个 verb 17 传第二个 verb,后面的 %#[1]x 又把 16 传过来,后面紧跟

1.5 错误类型

  • 错误类型或者未知 verb
  • 太多参数
  • 太少参数
  • 非整形的 width 和 precision
  • index 的错误使用

2 scan
scan 就是从格式话的文本中获取值放入变量中去。
Scan Scanf Scanln 是从标准输入读取
Fscan Fscanf Fscanln 是从 io.reader 中读取
Sscan Sscanf Sscanln 是从字符串中读取

函数对 ”n” 是怎么处理的?

  • Scan Fscan Sscan 把 ”n” 当作空格处理
  • Scanln Fscanln Sscanln 中 ”n” 是它的结束标志,Fscanln 同样把 EOF 作为结束标志
  • Scanf Fscanf Sscanf 取决于格式化字符串要求

Scan 系列函数接受指向特定类型的指针或者实现 Scan 方法的类型。

正文完
 0