Writing good Golang code
我正在掌握戈兰做事的方法。我将非常感谢任何能够在以下方面提供帮助的人。首先是一些示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package main import ( "log" "os" ) func logIt(s string) { f, _ := os.OpenFile("errors.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) defer f.Close() log.SetOutput(f) log.Println(s) } type iAm func(string) func a(iam string) { logIt(iam +" A") } func b(iam string) { logIt(iam +" B") } func c(iam string) { logIt(iam +" C") } var funcs = map[string]iAm{"A": a,"B": b,"C": c} func main() { funcs["A"]("Je suis") funcs["B"]("Ich bin") funcs["A"]("Yo soy") funcs["D"]("Soy Yo") } |
解释
- 我将所有的日志输出传输到一个文件中,以便稍后监控它。这是去频道的路吗?
- 我想根据用户输入确定在运行时调用的正确函数。为此,我将函数打包为一个golang映射-在PHP中,我将使用一个关联数组。这是可行的。然而,这是一种有效的做事方式吗?
- 最后,你会注意到我的地图上实际上没有D键。最后一个函数调用导致抛出一个摆动。在另一种语言中,我会用一次尝试来包装这些调用…阻止并避免了问题。据我所知,Go的理念是先检查钥匙的有效性,然后恐慌,而不是盲目使用钥匙。对吗?
我是一个新手,所以我可能有其他语言的行李。在我看来,以先发制人的方式处理特殊情况(使用前先检查钥匙)既不明智,也不高效。对吗?
登录到文件
每次我想记录一些东西时,都不会打开和关闭文件。在启动时,我只打开它一次并将其设置为输出,在程序存在之前,关闭它。我不会使用
函数映射完全正常,并且性能良好。如果需要更快的方法,可以根据函数名执行
但是,您可以在一个地方进行,您不必在每个呼叫中重复它:
1 2 3 4 5 | func call(name, iam string) { if fv := funcs[name]; fv != nil { fv(iam) } } |
注:
如果您选择使用
1 2 3 4 5 6 7 8 9 10 11 12 13 | func call(name, iam string) error { switch name { case"A": a(iam) case"B": b(iam) case"C": c(iam) default: return errors.New("Unknown function:" + name) } return nil } |
号错误处理/报告
In-Go函数可以有多个返回值,因此In-Go通过返回
因此,如果找不到指定的函数,
您可以选择返回由
1 | var ErrInvalidFunc = errors.New("Invalid function!") |
此解决方案的优点是,
1 2 3 4 5 6 7 | if err := call("foo","bar"); err != nil { if err == ErrInvalidFunc { //"foo" is an invalid function name } else { // Some other error } } |
。因此,完整的修订计划:
(稍微压实以避免垂直滚动条。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | package main import ("errors";"log";"os") type iAm func(string) func a(iam string) { log.Println(iam +" A") } func b(iam string) { log.Println(iam +" B") } func c(iam string) { log.Println(iam +" C") } var funcs = map[string]iAm{"A": a,"B": b,"C": c} func main() { f, err := os.OpenFile("errors.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { panic(err) } defer f.Close() log.SetOutput(f) call("A","Je suis") call("B","Ich bin") call("C","Yo soy") call("D","Soy Yo") } func call(name, iam string) error { if fv := funcs[name]; fv == nil { return errors.New("Unknown funcion:" + name) } else { fv(iam) return nil } } |