我正在学习 Go Lang,但在完成一个练习时遇到了问题:
https://tour.golang.org/methods/23
这个练习要求我实现 ROT13 加密。我决定使用从字节到旋转值的映射来实现加密,但我不确定初始化该映射的最佳方法。我不想使用文本初始化这个映射,而是希望通过循环整个字母表并在循环内设置 (键,值) 对的方式以编程方式初始化它。我还希望该映射仅可从 Rot13Reader 结构或对象中访问,并且所有实例都共享同一映射(而不是每个 Rot13Reader 对应一个副本)。
下面是我当前的 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)
}
我对这个方案有以下问题:
- 我不想在
main()
中准备rot13Map
- 我不想让
rot13Map
处于全局作用域。 - 我不想让每个
rot13Reader
副本都有单独的rot13Map
在Go语言中有什么办法可以实现我的要求吗?
var init = func (...) {...}
而不是func init(...) {...}
?(后者会导致编译器错误) - jlhawninit
,但当时我并不知道这个名称的重要性以及包级别的init
是如何工作的,因为Go Lang教程从未提过它。 - jlhawninit
似乎更适合于初中级话题。如果有第二个教程涵盖更高级的主题,比如init
、制作包(以及它们与$GOPATH
的关系,这一点我一开始觉得有些困惑)、结构体中的匿名字段和组合(我现在才刚刚开始学习),以及使用go
命令行工具,那就太好了。我在网络和golang.org上找到了分别涉及这些主题的地方,但不像入门教程那样集中在一个地方。 - jlhawn