为什么我的Go Reader不工作?

huangapple go评论84阅读模式
英文:

Why isn't my Go Reader working?

问题

我试图在Go中实现一个非常简单的io.Reader

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

// 我实现的非常简单的函数。
func (r *rot13Reader) Read(p []byte) (int, error) {
	return 5, nil // 现在只返回一些简单的值。
}

func main() {
	s := strings.NewReader(
		"Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}

最后,我希望rot13ReaderROT13应用于它正在读取的字符串,但现在,我只是尝试创建一个非常简单的io.Reader,以匹配正确的接口。

当我运行这个程序时,它永远不会停止。为什么?我在哪里有一个无限循环?


更新:我尝试通过下面的for循环修改data切片,但似乎并没有实际修改切片。我需要以某种方式复制data吗?

package main

import (

	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (r *rot13Reader) Read(data []byte) (int, error) {
	bytesRead, err := r.r.Read(data)
	
	// 尝试修改data... 只有在没有这个for循环时,文本才会打印在标准输出... 奇怪。
	for i := 0; i < bytesRead; i++ {
		data[i] += 13	
	}
	
	return bytesRead, err
}

func main() {
	s := strings.NewReader(
		"Lbh penpxrq gur pbqr!")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}
英文:

I tried to implement a very trivial io.Reader in Go:

package main

import (
	&quot;io&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

type rot13Reader struct {
	r io.Reader
}

// Very trivial function I implemented.
func (r *rot13Reader) Read(p []byte) (int, error) {
	return 5, nil // Return some trivial values for now.
}

func main() {
	s := strings.NewReader(
		&quot;Lbh penpxrq gur pbqr!&quot;)
	r := rot13Reader{s}
	io.Copy(os.Stdout, &amp;r)
}

In the end, I want rot13Reader to apply ROT13 to the string that it is reading, but for now, I am just trying to create a very trivial io.Reader that matches the proper interface.

When I run this program, it never halts. Why? Where do I have an infinite loop?


Update: I tried altering the data splice via the for loop below, but it doesn't seem to actually alter the splice. Do I need to somehow copy over data?

package main

import (

	&quot;io&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

type rot13Reader struct {
	r io.Reader
}

func (r *rot13Reader) Read(data []byte) (int, error) {
	bytesRead, err := r.r.Read(data)
	
	// Try to alter data... only without this for loop, text prints in standard output... odd.
	for i := 0; i &lt; bytesRead; i++ {
		data[i] += 13	
	}
	
	return bytesRead, err
}

func main() {
	s := strings.NewReader(
		&quot;Lbh penpxrq gur pbqr!&quot;)
	r := rot13Reader{s}
	io.Copy(os.Stdout, &amp;r)
}

答案1

得分: 8

io.Copy调用你的Read()方法连续地。

从文档中:

"Copy从src复制到dst,直到在src上达到EOF或发生错误。它返回复制的字节数和在复制过程中遇到的第一个错误(如果有)。

你需要发送EOF或返回一个错误。

这是一个更新的版本,它不会无限循环。

http://play.golang.org/p/UCfcw4S8yf

package main

import (
    "io"
    "os"
    "strings"
    "fmt"
)

type rot13Reader struct {
    r io.Reader
}

// 我实现的非常简单的函数。
func (r *rot13Reader) Read(p []byte) (int, error) {
    return 5, io.EOF // 现在只返回一些简单的值。
}

func main() {
    s := strings.NewReader(
        "Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
    fmt.Printf("Done copying...\n")
}

如果你想实际将字符串复制到输出中。你需要从rot13Reader.r中读取并将其复制到Read()方法中的p。

http://play.golang.org/p/dSCauz0uTw

package main

import (
    "io"
    "os"
    "strings"
    "fmt"
)

type rot13Reader struct {
    r io.Reader
}

// 我实现的非常简单的函数。
func (r *rot13Reader) Read(p []byte) (int, error) {
    i, err := r.r.Read(p)
    return i, err
}

func main() {
    s := strings.NewReader("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
    fmt.Printf("\nDone copying...\n")
}
英文:

io.Copy calls your Read() method continuously.

From the docs:

"Copy copies from src to dst until either EOF is reached
on src or an error occurs. It returns the number of bytes
copied and the first error encountered while copying, if any."

You need to either send EOF or return an error.

Here's an updated version that doesn't endless loop.

http://play.golang.org/p/UCfcw4S8yf

package main

import (
    &quot;io&quot;
    &quot;os&quot;
    &quot;strings&quot;
    &quot;fmt&quot;
)

type rot13Reader struct {
    r io.Reader
}

// Very trivial function I implemented.
func (r *rot13Reader) Read(p []byte) (int, error) {
    return 5, io.EOF // Return some trivial values for now.
}

func main() {
    s := strings.NewReader(
        &quot;Lbh penpxrq gur pbqr!&quot;)
    r := rot13Reader{s}
    io.Copy(os.Stdout, &amp;r)
    fmt.Printf(&quot;Done copying...\n&quot;)
}

If you want to actually copy the string to the output. You need to read from rot13Reader.r and copy it to p in the Read() method.

http://play.golang.org/p/dSCauz0uTw

package main

import (
    &quot;io&quot;
    &quot;os&quot;
    &quot;strings&quot;
    &quot;fmt&quot;
)

type rot13Reader struct {
    r io.Reader
}

// Very trivial function I implemented.
func (r *rot13Reader) Read(p []byte) (int, error) {
    i, err := r.r.Read(p)
    return i, err
}

func main() {
    s := strings.NewReader(&quot;Lbh penpxrq gur pbqr!&quot;)
    r := rot13Reader{s}
    io.Copy(os.Stdout, &amp;r)
    fmt.Printf(&quot;\nDone copying...\n&quot;)
}

huangapple
  • 本文由 发表于 2012年12月25日 03:31:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/14025056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定