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()
}
在某些语言中,通过提供接收项目的回调函数和 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()
}