如何从一系列函数中检索函数并调用它

kro*_*wiz 5 rebol rebol3

我正在尝试在Rebol 3中创建函数调度程序,以便程序接收到的每个字符串都有一个要调用的相关函数.

例如:

handlers: make map! [
  "foo" foo-func
  "bar" bar-func
]
Run Code Online (Sandbox Code Playgroud)

在哪里foo-funcbar-func是功能:

foo-func: func [ a b ] [ print "foo" ]
bar-func: func [ a b ] [ print "bar" ]
Run Code Online (Sandbox Code Playgroud)

这个想法是select从字符串开始的函数,所以:

f: select handlers "foo"
Run Code Online (Sandbox Code Playgroud)

因此执行f与执行相同foo-func,然后f使用一些参数调用:

f param1 param2
Run Code Online (Sandbox Code Playgroud)

我尝试引用中的单词map!,或使用get-words但没有成功.

get-word!在控制台上使用a ,无需通过map!它工作:

>> a: func [] [ print "Hello world!" ]
>> a
Hello world!
>> b: :a
>> b
Hello world!
Run Code Online (Sandbox Code Playgroud)

任何帮助赞赏.

Way*_*Cui 5

select handlers "foo"只得到这个词foo-func:

f: select handlers "foo"
probe f   ;will get: foo-func
Run Code Online (Sandbox Code Playgroud)

你需要得到它的内容:

f: get f
f 1 2    ;will print "foo"
Run Code Online (Sandbox Code Playgroud)

或者更紧凑:

f: get select handlers "foo"
Run Code Online (Sandbox Code Playgroud)


Bri*_*anH 4

最好在映射中实际引用该函数,而不是引用该函数的单词。如果您存储一个单词,那么您必须确保该单词绑定到一个引用该函数的对象,如下所示:

handlers: object [
    foo-func: func [ a b ] [ print "foo" ]
    bar-func: func [ a b ] [ print "bar" ]
]

handler-names: map [
    "foo" foo-func
    "bar" bar-func
]

apply get in handlers select handler-names name args
Run Code Online (Sandbox Code Playgroud)

但是,如果您只引用映射中的函数,则不必执行双重间接,并且您的代码如下所示:

handlers: map reduce [
    "foo" func [ a b ] [ print "foo" ]
    "bar" func [ a b ] [ print "bar" ]
]

apply select handlers name args
Run Code Online (Sandbox Code Playgroud)

代码更干净,效率也更高。或者如果你足够小心的话,就像这样:

handlers/(name) a b
Run Code Online (Sandbox Code Playgroud)

如果您希望代码在没有处理程序的情况下不执行任何操作,则上面的路径方法也将起作用 - 在您有可选处理程序的情况下(例如在 GUI 中)很常见。

您甚至可以使用不同的键名称对同一函数进行多次引用。您不必为单词分配功能,它们只是值。您还可以首先使用 path 方法收集处理程序,保存一个reduce.

handlers: make map! 10  ; preallocate as many entries as you expect
handlers/("foo"): func [ a b ] [ print "foo" ]
handlers/("bar"): func [ a b ] [ print "bar" ]
handlers/("baz"): select handlers "bar"  ; multiple references
Run Code Online (Sandbox Code Playgroud)

该路径语法只是调用 的另一种方式poke,但有些人更喜欢它。由于(希望是暂时的)语法冲突,我们必须将字符串值放在括号中,但在这些括号内,字符串键可以工作。do select它是or的更快替代方案poke