记录到文件
每次我想记录某些内容时,我不会打开和关闭文件。在启动时,我只需打开它一次并将其设置为输出,然后在程序存在之前将其关闭。我不会使用logIt()
功能:只需使用以下功能进行记录log https://golang.org/pkg/log/包,这样你就可以进行格式化日志记录,例如和log.Printf() https://golang.org/pkg/log/#Printf etc.
动态功能选择
函数映射完全没问题,并且在性能方面表现良好。如果你需要更快的东西,你可以做switch
根据函数名直接调用目标函数case
分支机构。
检查密钥是否存在
中的值map
是函数值。函数类型的零值是nil
你不能打电话给nil
函数,因此您必须在继续调用它之前检查该值。请注意,如果您使用不存在的键对映射进行索引,则返回值类型的零值,即nil
如果是函数类型。所以我们可以简单地检查该值是否为nil
。还有另一种逗号惯用语,例如fv, ok := funcs[name]
where ok
将是一个布尔值,告诉您是否在地图中找到了该键。
不过,您可以在一个地方完成此操作,而不必在每次调用中重复它:
func call(name, iam string) {
if fv := funcs[name]; fv != nil {
fv(iam)
}
}
Note:
如果您选择使用switch
, the default
分支将处理无效的函数名称(这里当然不需要函数映射):
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
}
错误处理/报告
在 Go 中,函数可以有多个返回值,因此在 Go 中,您可以通过返回一个来传播错误error https://golang.org/pkg/builtin/#error值,即使该函数通常有其他返回值。
So the call()
函数应该有一个error
如果找不到指定的函数,则返回类型以发出信号。
您可以选择退回新的error
创造的价值,例如这errors.New() https://golang.org/pkg/errors/#New函数(因此它可以是动态的),或者您可以选择创建一个全局变量并具有固定的错误值,例如:
var ErrInvalidFunc = errors.New("Invalid function!")
该解决方案的优点是调用者call()
函数可以比较返回的error
的值对的值ErrInvalidFunc
全局变量来了解这种情况并采取相应的行动,例如:
if err := call("foo", "bar"); err != nil {
if err == ErrInvalidFunc {
// "foo" is an invalid function name
} else {
// Some other error
}
}
所以完整修改后的程序:
(Slightly compacted to avoid vertical scroll bars.)
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
}
}