突破递归函数
Breaking out of a recursive function
我正在遍历一组嵌套块,当我找到我正在寻找的值时想停止行走。
出于超出此问题范围的原因,我无法针对此特定问题使用 PARSE,也无法将 FOREACH 用作循环程序:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
如果我找到这个特定值,我想爆发
walk [a [b c [d e] f] g] [if value = 'e [return value]]
; returns 'e
不过我也想做不爆的操作:
walk [a [b c [d e] f] g] [
collect [if find [c e] value [keep value]]
]
; returns [c e]
想尝试解决包括 Red 在内的任何 Rebol 风格的问题。关于效率的任何想法(我使用块而不是函数的原因)等也将受到欢迎。
我正在寻找的功能组合是 CATCH/THROW。再次使用给定的函数:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
我可以简单的包装如下:
catch [walk [a [b c [d e] f] g] [if value = 'e [throw value]]]
; returns 'e
一些笔记
- 如果没有匹配项
,我希望函数 return NONE
我只是走 return NONE(我使用 ALSO 只是为了不留下尴尬的尾随 none
):
walk: func [series [block!] criteria [block!]][
also none use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
- red 没有 USE 函数
这引入了复杂性,因为我 仅 想将块绑定到单词 VALUE。如果我按如下方式重写函数:
walk: func [series [block!] criteria [block!] /local value][
do bind compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
] 'value
]
然后它还将同一块绑定到单词 SERIES 和 CRITERIA,这将覆盖调用上下文中任何此类单词的绑定,例如:
walk [some values][series: none probe value] ; results in error
此版本避免绑定除 VALUE 之外的任何内容,并在 Red 0.6.3 和 Rebol2 中工作:
walk: func [series [block!] criteria [block!]][
also none do bind compose/deep [
while [not tail? series] [
value: pick series 1
either block? value [
walk value criteria
] [
(to paren! criteria)
]
series: next series
]
]
context [value: none]
]
(欢迎评论此实现与 USE 的不同之处。)
是的,这不适用于 Rebol3 Alpha。但是使用 USE 的那个也没有。我认为这是一个 THROW 问题。
我正在遍历一组嵌套块,当我找到我正在寻找的值时想停止行走。
出于超出此问题范围的原因,我无法针对此特定问题使用 PARSE,也无法将 FOREACH 用作循环程序:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
如果我找到这个特定值,我想爆发
walk [a [b c [d e] f] g] [if value = 'e [return value]]
; returns 'e
不过我也想做不爆的操作:
walk [a [b c [d e] f] g] [
collect [if find [c e] value [keep value]]
]
; returns [c e]
想尝试解决包括 Red 在内的任何 Rebol 风格的问题。关于效率的任何想法(我使用块而不是函数的原因)等也将受到欢迎。
我正在寻找的功能组合是 CATCH/THROW。再次使用给定的函数:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
我可以简单的包装如下:
catch [walk [a [b c [d e] f] g] [if value = 'e [throw value]]]
; returns 'e
一些笔记
- 如果没有匹配项 ,我希望函数 return NONE
我只是走 return NONE(我使用 ALSO 只是为了不留下尴尬的尾随 none
):
walk: func [series [block!] criteria [block!]][
also none use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
- red 没有 USE 函数
这引入了复杂性,因为我 仅 想将块绑定到单词 VALUE。如果我按如下方式重写函数:
walk: func [series [block!] criteria [block!] /local value][
do bind compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
] 'value
]
然后它还将同一块绑定到单词 SERIES 和 CRITERIA,这将覆盖调用上下文中任何此类单词的绑定,例如:
walk [some values][series: none probe value] ; results in error
此版本避免绑定除 VALUE 之外的任何内容,并在 Red 0.6.3 和 Rebol2 中工作:
walk: func [series [block!] criteria [block!]][
also none do bind compose/deep [
while [not tail? series] [
value: pick series 1
either block? value [
walk value criteria
] [
(to paren! criteria)
]
series: next series
]
]
context [value: none]
]
(欢迎评论此实现与 USE 的不同之处。)
是的,这不适用于 Rebol3 Alpha。但是使用 USE 的那个也没有。我认为这是一个 THROW 问题。