15

私は現在、Go Lang チュートリアルに取り組んでいますが、演習の 1 つで問題が発生しました。

https://tour.golang.org/methods/23

この演習では、ROT13 暗号を実装します。バイトから回転された値へのマップを使用して暗号を実装することにしましたが、このマップを初期化する最良の方法がわかりません。リテラルを使用してマップを初期化したくはありませんが、ループ内でアルファベットをループし、(キー、値) ペアを設定することにより、プログラムで実行することをお勧めします。また、マップが Rot13Reader 構造体/オブジェクトからのみアクセス可能になり、すべてのインスタンス (?) が同じマップを共有するようにしたいと考えています (Rot13Reader ごとに 1 つのコピーではなく)。

これが私の現在の作業Goプログラムです:

package main

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

type rot13Reader struct {
    r io.Reader
}

var rot13Map = map[byte]byte{}

func (rotr *rot13Reader) Read(p []byte) (int, error) {
    n, err := rotr.r.Read(p)
    for i := 0; i < n; i++ {
        if sub := rot13Map[p[i]]; sub != byte(0) {
            p[i] = sub
        }
    }
    return n, err
}

func main() {
    func() {
        var uppers = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
        var lowers = []byte("abcdefghijklmnopqrstuvwxyz")

        var init = func (alphabet []byte) {
            for i, char := range alphabet {
                rot13_i := (i + 13) % 26
                rot13Map[char] = alphabet[rot13_i]
            }
        }

        init(uppers)
        init(lowers)
    }()

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

これで私が抱えている問題は次のとおりです。

  • 準備しなくていいrot13Mapmain()
  • rot13Map私はグローバルスコープになりたくありません。
  • rot13Readera の各コピーに個別の a を持たせたくないrot13Map

Goで私が望むものを達成する方法はありますか?

4

3 に答える 3

15

これを行うには、rot13 パッケージを作成します。プログラムで init() 関数でマップを作成し、すべての rot13 デコーダーにグローバルなパッケージ レベルとして提供できます。パッケージがインポートされると、init 関数が実行されます。

Rot13Reader はパッケージ内の唯一のタイプであるため、マップにアクセスできる唯一のタイプです。

警告: すべてのコードはテストされていません。

package rot13

import (
    "io"
)

var rot13Map = map[byte]byte{}

func init() {
    var uppers = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    var lowers = []byte("abcdefghijklmnopqrstuvwxyz")

    var init = func(alphabet []byte) {
        for i, char := range alphabet {
            rot13_i := (i + 13) % 26
            rot13Map[char] = alphabet[rot13_i]
        }
    }

    init(uppers)
    init(lowers)
}

type Reader struct {
    r io.Reader
}

func (rotr Reader) Read(p []byte) (int, error) {
    n, err := rotr.r.Read(p)
    for i := 0; i < n; i++ {
        if sub := rot13Map[p[i]]; sub != byte(0) {
            p[i] = sub
        }
    }
    return n, err
}

もちろん、go ツアーで別のパッケージを作成することはできません。メインからアクセスできる rot13Map に固執しています。必要な分離を取得するには、ローカルで Go を実行する必要があります。

于 2013-05-05T02:55:32.247 に答える