50.Go fmt包

标准库中的fmt包可以格式化字符串和从字符串中解析数据.

基本的fmt

包fmt使用格式动词实现格式化的I/O:

  • %v 默认格式
  • %T 值的类型
  • %s 字符串或片的未解释字节

格式化函数

fmt中有4个主要的函数类型,和它们的几个变体。

Print, Println, Printf

fmt.Print("Hello World")        // prints: Hello World
fmt.Println("Hello World")      // prints: Hello World\n
fmt.Printf("Hello %s", "World") // prints: Hello World

Sprintf

formattedString := fmt.Sprintf("%v %s", 2, "words") // returns string "2 words"

Fprint

byteCount, err := fmt.Fprint(w, "Hello World") // writes to io.Writer w

Fprint可以在http handlers中使用:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello %s!", "Browser")
}   // Writes: "Hello Browser!" to HTTP response

Scan

Scan从标准输入中扫描文本

var s string
fmt.Scanln(&s) // pass pointer to buffer
// Scanln is similar to fmt.Scan(), but it stops scanning at new line.
fmt.Println(s) // whatever was inputted

Stringer接口

fmt.Stringer接口由一个 String()string 函数组成:

type Stringer interface {
    String() string
}

目的是为一个值提供字符串表示形式。

如果在类型上定义String()方法,则字符串格式化方法(如fmt.Printf)将其用于%s格式化指令:

type User1 struct {
    Name  string
    Email string
}

type User2 struct {
    Name  string
    Email string
}

// String satisfies the fmt.Stringer interface
// Defining it on type User2 makes it available on *User2 as well
func (u User2) String() string {
    return fmt.Sprintf("%s <%s>", u.Name, u.Email)
}

func main() {
    u1 := &User1{
        Name:  "John Doe",
        Email: "johndoe@example.com",
    }

    fmt.Printf("u1: type: %T, value: %s\n\n", u1, u1)

    u2 := User2{
        Name:  "John Doe",
        Email: "johndoe@example.com",
    }

    fmt.Printf("u2: type:  %T, value: %s\n\n", u2, u2)

        // method define on type User2 is also available on type *User2
    u3 := &User2{
        Name:  "John Doe",
        Email: "johndoe@example.com",
    }

    fmt.Printf("u3: type: %T, value: %s\n", u3, u3)
}

u1: type: *main.User1, value: &{John Doe johndoe@example.com}
u2: type: main.User2, value: John Doe johndoe@example.com
u3: type: *main.User2, value: John Doe johndoe@example.com

类型User1没有实现Stringer接口,因此%s使用结构的标准格式显示它。

类型User2实现了Stringer接口,因此%s使用String()方法获取值。

类型User2和* User2不同。

但是,为方便起见,在User2上定义的方法也可以在* User2上使用(但反之则不行)。

因此,最好在struct上定义String()方法,而不是struct的指针。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容