true 还是 false 应该终止回调迭代?

Should true or false terminate callback iteration?

在某些语言中,通过提供接收项目的回调函数和 returns 指示是继续还是停止迭代的布尔值来进行迭代是必要的或更清晰的。

哪个是表示希望 stop/continue 的首选值?为什么?有哪些先例?

Go 中的示例:

func IntSliceEach(sl []int, cb func(i int) (more bool)) (all bool) {
    for _, i := range sl {
        if !cb(i) {
            return false
        }
    }
    return true
}

Which is the preferred value to indicate desire to stop/continue?

true 继续

Why?

示例 1:

func example(i interface{}) {
    if w, ok := i.(io.Writer); ok {
        // do something with your writer, ok indicates that you can continue
    }
}

示例 2:

var sum int = 0
it := NewIntStatefulIterator(int_data)
for it.Next() {
    sum += it.Value()
}

在这两种情况下都是 true (ok) 表示您应该继续。所以我认为这将是您的示例的方式。

前言: 以下答案适用于回调函数,该函数根据当前项目决定循环是否应提前终止 - 这就是您所问的。

这不要与如果有更多元素要处理则进行和报告的函数混淆,其中 true return 值通常被接受以表示有更多元素(一个很好的例子是 Scanner.Scan()),其典型用法是:

scanner := bufio.NewScanner(input)
for scanner.Scan() {
    // Process current item (line):
    line := scanner.Text()
    fmt.Println(line) // Do something with line
}

坚持bool return类型

通常 returning true 来指示终止导致代码更易于阅读。这是由于 for 的性质:如果你什么都不做,for 继续,所以你必须显式地 break 如果你想提前终止,所以有一个干净的终止条件更重要常见。

但这是一个品味问题。你可以随心所欲,但重要的是以有意义的方式命名回调函数,清楚地说明其 return 值的含义,因此查看代码(使用它的条件)将易于理解。

例如,以下名称是好的并且 return 值是明确的:

// A return value of true means to terminate
func isLast(item Type) bool
func terminateAfter(item Type) bool
func abort(item Type) bool

// A return value of true means to continue (not to terminate)
func keepGoing(item Type) bool
func carryOn(item Type) bool
func processMore(item Type) bool

在易于理解的代码中使用这些结果:

for i, v := range vals {
    doSomeWork()
    if terminateAfter(v) {
        break // or return
    }
}

for i, v := range vals {
    doSomeWork()
    if !keepGoing(v) {
        break // or return
    }
}

// Or an alternative to the last one (subjective which is easier to read):

for i, v := range vals {
    doSomeWork()
    if keepGoing(v) {
        continue
    }
    break
}

作为反例,以下回调函数名称不好,因为您无法猜测它们的 return 值是什么意思:

// Bad: you can't tell what return value of true means just by its name:
func test(item Type) bool
func check(item Type) bool

具有 error return 类型

回调不仅测试而且还对传递的项目进行一些处理也很常见。在这些情况下,return 一个 error 而不是 bool 是有意义的。这样做,显然 nil return 值表示成功(并继续),非 nil 值表示错误并且处理应该停止。

func process(item Type) error

for i, v := range vals {
    if err := process(v); err != nil {
        // Handle error and terminate
        break
    }
}

具有类似枚举的 return 值

此外,如果多个 return 值有意义,您可以选择为 return 值定义常量,您可以命名这些常量。

type Action int
const (
    ActionContinue Action = iota
    ActionTerminate
    ActionSkip
)

func actionToTake(item Type) Action

for i, v := range vals {
    switch actionToTake(v) {
    case ActionSkip:
        continue
    case ActionTerminate:
        return
    }
    doSomeWork()
}