在 Go 中实现 io.Writer 接口

RdB*_*RdB 3 interface go

我正在尝试通过“Write”方法创建一个满足 io.Writer 接口的结构类型:

package main

import (
    "fmt"
)

type Person struct {
    name []byte
}

func (p Person) Write(data []byte) (n int, err error) {
    p.name = data
    return len(data), nil
}

func main() {
    b := []byte("Dave")
    person := Person{}
    fmt.Fprint(person, b)
    fmt.Printf("Person name: %s\n", person.name)
}
Run Code Online (Sandbox Code Playgroud)

但指令

fmt.Fprint(person, b)
Run Code Online (Sandbox Code Playgroud)

不起作用,person.Name 仍然是空切片。为什么?先感谢您。

Eug*_*sky 9

关于值和指针接收器两美分。可以通过两种方式定义Write满足函数io.Writer

func (p Person) Write(data []byte) (n int, err error) {
...
}
Run Code Online (Sandbox Code Playgroud)

这种方法对 的副本进行操作Person,这就是为什么在函数完成后您看不到更改的原因。

和:

func (p *Person) Write(data []byte) (n int, err error) {
...
}
Run Code Online (Sandbox Code Playgroud)

这种方式函数使用指向原始Person. 这就是为什么在函数结束后变化是可见的。


Sto*_*ica 7

如果你想让Write函数修改接收者对象,你必须让接收者成为一个指针:

func (p *Person) Write(data []byte) (n int, err error) {
    p.name = data
    return len(data), nil
}
Run Code Online (Sandbox Code Playgroud)

fmt.Fprint函数对其操作数使用默认格式。这不是你想要的,你想写bas的内容"%s",所以你需要使用fmt.Fprintf

func main() {
    b := []byte("Dave")
    person := Person{}
    fmt.Fprintf(&person, "%s", b)
    fmt.Printf("Person name: %s\n", person.name)
}
Run Code Online (Sandbox Code Playgroud)

操场上见。