gpt4 book ai didi

arrays - Golang 最佳实践 : empty array response or error?

转载 作者:行者123 更新时间:2023-12-01 22:27:09 25 4
gpt4 key购买 nike

对于接受对象 slice 并返回另一个对象 slice (理想情况下与输入数组长度相同)以及错误的函数,在错误处理方面的最佳实践如下:

func ([]interface{}) ([]interface{}, error)

一种方法是,每当您在处理 slice 中的一个对象时遇到错误时,您都会返回错误响应,但是在接收函数中,如果您不丢弃所有 slice 元素,错误响应就变得毫无用处,只是告诉我们认为处理其中一个元素或全部失败。另一种方法是在没有处理任何元素时返回错误,但我觉得这又没什么用。另一种方法是您不包含错误作为返回对象,而是对于每个 slice 元素结构,将其自己的错误对象作为复合对象,以便您可以将元素错误作为输出发送。

最好的方法显然取决于特定的场景,但是,我想知道人们是否遵循任何最佳实践或围绕这个问题的任何设计模式。

PS:这是最接近的问题之一,但是由于它接受单个对象作为输入,因此不太相关:
Return empty array or error

最佳答案

... a function that accepts [slice of interface representing an] array of objects and returns another [slice of interface representing an] array of objects along with error ...



你没有告诉我们足够多的事情继续下去。
  • 返回的 slice 实际上与参数 slice 有什么关系吗?
  • 如果有,他们有什么关系?例如,返回的 slice 可能应该是输入 slice 大小的一半,当且仅当输入对象的数量为奇数时才会发生错误,在这种情况下,最后一个输入对象已被忽略。
  • 输入必须按顺序处理,还是并行处理?

  • One more way is you don't include error as return object and instead with every array object struct, have it's own error object as a composite so you can send elementwise error as output.



    如果输出与输入是一对一的,并且您打算并行处理它们和/或在达到一个坏的输入时继续处理剩余的输入,这可能是一种明智的方法。等效地,您可以让输出 slice 包含错误。

    这真的非常依赖问题。

    编辑:考虑,例如,以下(我不认为这是好的,请注意):
    const maxWorkers = 10 // tunable

    // Process a slice of T's in parallel. The results are either an
    // R for each T, or an error. Caller provides the actual function
    // f(T), which returns R + error (an empty/zero R for error).
    func ProcessInParallel(input []T, f func(T) (R, error)) ([]interface{}, error) {
    // Make one channel for sending work to workers,
    // and one for receiving results from workers.
    type Todo struct {
    i int // the index of the item
    item T // the item to work on
    }
    workChan := make(chan Todo)
    type Done struct {
    i int // the index of the item worked on
    r R // result, if we have one
    e error // error, if we have one
    }
    doneChan := make(chan Done)

    // Spin off workers: maxWorkers or len(input),
    // whichever is smaller.
    n := len(input)
    if n > maxWorkers {
    n = maxWorkers
    }
    var wg sync.WaitGroup
    for i := 0; i < n; i++ {
    wg.Add(1)
    go func(i int) {
    for todo := range workChan {
    i := todo.i
    r, err := f(input[i])
    doneChan <- Done{i, r, err}
    }
    wg.Done()
    }(i)
    }

    // Close doneChan when all workers finish.
    go func() {
    wg.Wait()
    close(doneChan)
    }()

    // Hand out work to workers (then close work channel).
    go func() {
    for i := range input {
    workChan <- Todo{i, input[i]}
    }
    close(workChan)
    }()

    // Collect results.
    var anyErr error
    ret := make([]interface{}, len(input))
    for done := range doneChan {
    i := done.i
    r, err := done.r, done.e
    if err != nil {
    anyErr = err
    ret[i] = err
    } else {
    ret[i] = r
    }
    }
    return ret, anyErr
    }

    这有一个整体错误返回,它返回 interface{} 的一部分.这意味着您可以立即判断一切是否正常。但是,使用起来有点烦人:
    ret, err := ProcessInParallel(arg, f)
    if err != nil {
    fmt.Println("some inputs failed")
    for i := range ret {
    if e, ok := ret[i].(error); ok {
    fmt.Printf("%d: failed: %v\n", i, e)
    } else {
    fmt.Printf("%d: %s\n", i, ret[i].(R))
    }
    }
    } else {
    fmt.Println("all inputs were good")
    for i := range ret {
    fmt.Printf("%d: %s\n", i, ret[i].(R))
    }
    }

    为什么要打扰所有错误摘要?

    相反,我们可以有 ProcessInParallel返回 []R, []error ,例如,或者——可能更好——使用简单的 error接口(interface)返回值存储一个 MultiError作为 Cerise Limón suggested in a comment :
    ret, err := ProcessInParallel(arg, f)
    if err != nil {
    if merr, ok := err.(datastore.MultiError); ok {
    // merr[i] indicates the various failed items
    // any ret[i] for which merr[i] is nil is OK
    }
    } else {
    // all ret[i] are ok
    }

    一个不使用 MultiError 的工作示例是 here .

    一个使用 MultiError 的工作示例是 here .

    关于arrays - Golang 最佳实践 : empty array response or error?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59331825/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com