在Go中把结构体转换为io.Reader教程

1,605 阅读1分钟

要将一个结构体转换为 io.Reader并将其作为HTTP POST请求体发送,您需要将该对象编码为字节表示,例如JSON。编码的结果应该存储在 bytes.Bufferbytes.Reader对象中,这些对象实现了 io.Reader接口中。

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "net/http"
)

type Fruit struct {
    Name  string `json:"name"`
    Color string `json:"color"`
}

func main() {
    // encode a Fruit object to JSON and write it to a buffer

    f := Fruit{

        Name:  "Apple",

        Color: "green",

    }

    var buf bytes.Buffer

    err := json.NewEncoder(&buf).Encode(f)

    if err != nil {

        log.Fatal(err)

    }


    client := &http.Client{}
    req, err := http.NewRequest(http.MethodPost, "https://postman-echo.com/post", &buf)
    if err != nil {
        log.Fatal(err)
    }
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }

    bytes, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(bytes))
}

在第19-27 行中,我们创建了一个新的Fruit 结构实例,并通过以下方式将其编码为JSON json.Encoder.其结果被写入一个 bytes.Buffer,它实现了 io.Writerio.Reader接口。通过这种方式,我们不仅可以把这个缓冲区作为一个 io.Writer来存储JSON结果,还可以作为 io.Reader当进行POST请求时,需要用到这个结构。

另外,你也可以使用函数将该结构编码为JSON字节片,并创建一个新的 json.Marshal()函数将结构体编码为JSON字节片,并创建一个新的 bytes.Reader的结构,用于从该片段中读取数据,该结构实现了所需的 io.Reader接口。

f := Fruit{
    Name:  "Apple",
    Color: "green",
}
data, err := json.Marshal(f)
if err != nil {
    log.Fatal(err)
}
reader := bytes.NewReader(data)

client := &http.Client{}
req, err := http.NewRequest(http.MethodPost, "https://postman-echo.com/post", reader)