doutangu4671 2013-05-05 01:56
浏览 168
已采纳

Go中的静态初始化?

I'm currently working on the Go Lang tutorial, but ran into problem with one of the exercises:

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

The exercise has me implement a ROT13 cipher. I decided to implement the cipher using a map from a byte to its rotated value but I'm not sure of the best way to initialize this map. I don't want to initialize the map using a literal, but would prefer to do it programmatically by looping through an alphabet and setting (key, value) pairs within the loop. I would also like the map to only be accessible from Rot13Reader struct/object and have all instances(?) share the same map (rather than one copy per Rot13Reader).

Here's my current working Go program:

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)
}

Here are the problems I have with this:

  • I don't want to have to prepare rot13Map in main()
  • I don't want rot13Map to be in global scope.
  • I don't want each copy of a rot13Reader to have a separate rot13Map

Is there a way to achieve what I want in Go?

  • 写回答

3条回答 默认 最新

  • douluo6626 2013-05-05 02:55
    关注

    In order to do this, I would make a rot13 package. You can programmatically create the map in an init() function and provide it as a package level global to all your rot13 decoders. The init function runs when your package is imported.

    Because Rot13Reader is the only type in the package, it is the only one able to access your map.

    WARNING: All code untested.

    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
    }
    

    Obviously, you can't make another package in the go tour. You are stuck with rot13Map being accessible by main. You will need to run Go locally to get the separation you want.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题