การรับข้อความแสดงข้อผิดพลาด "bytes.Buffer ไม่ได้ใช้ io.Writer"


104

ฉันกำลังพยายามให้ Go object ใช้ io.Writer แต่เขียนลงในสตริงแทนที่จะเป็นไฟล์หรืออ็อบเจกต์แบบไฟล์ ผมคิดว่าจะทำงานตั้งแต่การดำเนินการมันbytes.Buffer Write(p []byte)อย่างไรก็ตามเมื่อฉันลองสิ่งนี้:

import "bufio"
import "bytes"

func main() {
    var b bytes.Buffer
    foo := bufio.NewWriter(b)
}

ฉันได้รับข้อผิดพลาดต่อไปนี้:

cannot use b (type bytes.Buffer) as type io.Writer in function argument:
bytes.Buffer does not implement io.Writer (Write method has pointer receiver)

ฉันสับสนเนื่องจากมันใช้อินเทอร์เฟซอย่างชัดเจน ฉันจะแก้ไขข้อผิดพลาดนี้ได้อย่างไร


2
ฉันพบปัญหานี้อย่างน้อยสองครั้งและ Googling สำหรับวิธีแก้ปัญหาก็ไม่มีประโยชน์จริงๆ
Kevin Burke

11
โปรดทราบว่าไม่จำเป็นต้องสร้าง bufio เพียงใช้ & b เป็น io ผู้เขียน
Vivien

คำตอบ:


157

ส่งตัวชี้ไปยังบัฟเฟอร์แทนบัฟเฟอร์เอง:

import "bufio"
import "bytes"

func main() {
    var b bytes.Buffer
    foo := bufio.NewWriter(&b)
}

4
ฉันพบสิ่งนี้และสนใจที่จะเรียนรู้ว่าทำไมจึงเป็นเช่นนั้น ฉันค่อนข้างไม่คุ้นเคยกับคำแนะนำใน Go
ชั่วโมงกลับ

2
ขอบคุณเควินความผิดพลาดง่ายๆนี้ใช้เวลาหนึ่งชั่วโมงกว่าที่ฉันจะทำสิ่งนี้ได้ :)
Nelo Mitranim

8
@hourback เกี่ยวข้องกับวิธีการใช้งานอินเทอร์เฟซ มีหลายวิธีในการติดตั้งอินเทอร์เฟซใน Go ทั้งที่มีตัวรับค่าหรือตัวชี้ ฉันคิดว่านี่เป็นสิ่งที่แปลกประหลาดจริงๆสำหรับ Go หากอินเทอร์เฟซถูกนำไปใช้โดยใช้ตัวรับค่าทางใดทางหนึ่งก็ใช้ได้ แต่ถ้าอินเทอร์เฟซถูกนำมาใช้โดยใช้ตัวรับตัวชี้คุณต้องส่งตัวชี้ไปยังค่าหากคุณต้องการใช้อินเทอร์เฟซ มันสมเหตุสมผลแล้วเนื่องจากผู้เขียนต้องกลายพันธุ์บัฟเฟอร์เพื่อติดตามว่าหัวของนักเขียนอยู่ที่ไหน
John Leidegren

26
package main

import "bytes"
import "io"

func main() {
    var b bytes.Buffer
    _ = io.Writer(&b)
}

คุณไม่จำเป็นต้องใช้ "bufio.NewWriter (& b)" เพื่อสร้าง io.Writer & b เป็น io ตัวเขียนเอง


1
นี่น่าจะเป็นคำตอบที่ใช่ หากคุณพยายามสร้างนักเขียนใหม่จากบัฟเฟอร์คุณจะไม่สามารถดึงข้อมูลบัฟเฟอร์ไบต์ได้โดยตรงซึ่งทำให้สิ่งต่างๆซับซ้อนมากขึ้น
onetwopunch

ฉันอยากจะเข้าใจว่าสิ่งนี้กำลังทำอะไรอยู่? เป็นเพียงการตรวจสอบว่า b ใช้อินเทอร์เฟซ Writer หรือไม่? _ = io.Writer (& b)
Aki

8

เพียงแค่ใช้

foo := bufio.NewWriter(&b)

เนื่องจากทางไบต์บัฟเฟอร์ใช้ io.Writer คือ

func (b *Buffer) Write(p []byte) (n int, err error) {
    ...
}
// io.Writer definition
type Writer interface {
    Write(p []byte) (n int, err error)
}

มันไม่ได้b *Buffer b Buffer(ฉันคิดว่ามันแปลกที่เราสามารถเรียกวิธีการโดยใช้ตัวแปรหรือตัวชี้ได้ แต่เราไม่สามารถกำหนดตัวชี้ให้กับตัวแปรประเภทที่ไม่ใช่ตัวชี้ได้)

นอกจากนี้พรอมต์คอมไพเลอร์ยังไม่ชัดเจนเพียงพอ:

bytes.Buffer does not implement io.Writer (Write method has pointer receiver)


ความคิดบางอย่างใช้ไปPassed by valueถ้าเราผ่านbไปbuffio.NewWriter()ใน NewWriter () มันเป็นใหม่b(กันชนใหม่) &bไม่เดิมบัฟเฟอร์ที่เรากำหนดไว้ดังนั้นเราจึงจำเป็นต้องผ่านอยู่

ผนวกอีกครั้งไบต์บัฟเฟอร์ถูกกำหนด:

type Buffer struct {
    buf       []byte   // contents are the bytes buf[off : len(buf)]
    off       int      // read at &buf[off], write at &buf[len(buf)]
    bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation.
    lastRead  readOp   // last read operation, so that Unread* can work correctly.
}

การใช้passed by valueโครงสร้างบัฟเฟอร์ใหม่ที่ส่งผ่านจะแตกต่างจากตัวแปรบัฟเฟอร์ต้นทาง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.