4

io.Reader私はGoで非常に些細なことを実装しようとしました:

package main

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

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(
        "Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}

結局、私はそれが読んでいる文字列にROT13rot13Readerを適用したいのですが、今のところ、私は適切なインターフェースに一致する非常に些細なものを作成しようとしています。io.Reader

このプログラムを実行すると、停止することはありません。なんで?無限ループはどこにありますか?


更新:data以下のforループを介してスプライスを変更しようとしましたが、実際にはスプライスが変更されていないようです。どういうわけかコピーする必要があり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)

    // Try to alter data... only without this for loop, text prints in standard output... odd.
    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)
}
4

1 に答える 1

8

io.CopyはRead()メソッドを継続的に呼び出します。

ドキュメントから:

「srcでEOFに達するか、エラーが発生するまで、srcからdstにコピーをコピーします。コピーされたバイト数と、コピー中に発生した最初のエラー(存在する場合)を返します。」

EOFを送信するか、エラーを返す必要があります。

これは、無限にループしない更新バージョンです。

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

package main

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

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(
        "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
}

// 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("Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
    fmt.Printf("\nDone copying...\n")
}
于 2012-12-24T19:40:12.493 に答える