编写好的Golang代码

DroidOS:

我正在掌握Golang的处理方式。对于可能在以下方面提供帮助的任何人,我将非常感激。首先一些示例代码

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键。最后一个func调用导致Go摆动。用另一种语言,我会将那些调用包装在try ...块中,从而避免了该问题。从我所了解的围棋理念是检查密钥的有效性第一和恐慌,而不是试图盲目地使用该密钥。那是对的吗?

我是Go新手,因此我可能会受到其他使用语言的困扰。在我看来,以先发制人的方式处理特殊情况(在使用前先检查钥匙)既不明智也不有效。对?

icza:

记录到文件

每当我想记录某些内容时,我都不会打开和关闭文件。在启动时,我只需将其打开一次并将其设置为输出,然后在程序存在之前将其关闭。而且我不会使用logIt()函数:仅使用log的函数进行日志记录,因此您可以进行格式化日志记录,例如使用log.Printf()etc等。

动态功能选择

一个功能图完全可以,并且在性能方面做得很好。如果您需要更快的速度,则可以switch基于函数名称进行操作,然后直接在case分支中调用目标函数

检查密钥是否存在

中的值map是函数值。函数类型的零值为,nil并且您不能调用nil函数,因此必须在继续调用之前检查该值。请注意,如果使用不存在的键索引地图,则返回值类型的零值(对于nil函数类型)。因此,我们可以简单地检查该值是否为nil还有另一个逗号分隔的习惯用语,例如fv, ok := funcs[name]ok将是一个布尔值,告诉您是否在地图中找到了密钥。

不过,您可以在一个地方完成此操作,而不必在每个调用中都重复该操作:

func call(name, iam string) {
    if fv := funcs[name]; fv != nil {
        fv(iam)
    }
}

注意:

如果您选择使用switch,则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,即使函数通常具有其他返回值,您也可以通过返回值来传播错误

因此,如果找不到指定的函数,则call()函数应具有error返回类型以发出信号。

您可以选择返回errorerrors.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
    }
}

因此,完整的修订程序:

(稍微压紧以避免垂直滚动条。)

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章