我正在尝试在Rebol 3中创建函数调度程序,以便程序接收的每个字符串都有一个要调用的相关函数。
例如:
handlers: make map! [
"foo" foo-func
"bar" bar-func
]
其中foo-func
和bar-func
是函数:
foo-func: func [ a b ] [ print "foo" ]
bar-func: func [ a b ] [ print "bar" ]
这个想法是select
从字符串开始的函数,所以:
f: select handlers "foo"
这样执行f
与执行foo-func
相同,然后使用一些参数调用f
:
f param1 param2
我尝试引用map!
中的字词,或使用get-words但没有成功。
在控制台上使用get-word!
,无需通过map!
就可以了:
>> a: func [] [ print "Hello world!" ]
>> a
Hello world!
>> b: :a
>> b
Hello world!
任何帮助表示感谢。
答案 0 :(得分:5)
select handlers "foo"
只能得到foo-func
:
f: select handlers "foo"
probe f ;will get: foo-func
您需要获取其内容:
f: get f
f 1 2 ;will print "foo"
或更紧凑:
f: get select handlers "foo"
答案 1 :(得分:4)
foo-func只是一个未评估的单词
>> type? select handlers "foo"
== word!
首先应创建函数,然后减少块,用于创建处理程序映射,以便
handlers: make map! reduce [
"foo" :foo-func
"bar" :bar-func
]
然后你在地图中有功能
>> type? select handlers "foo"
== function!
答案 2 :(得分: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
但是如果您只是在地图中引用了该功能,则不必进行双重间接,您的代码如下所示:
handlers: map reduce [
"foo" func [ a b ] [ print "foo" ]
"bar" func [ a b ] [ print "bar" ]
]
apply select handlers name args
更清洁的代码,也更高效。或者如果你足够小心,就像这样:
handlers/(name) a b
如果你希望代码在没有处理程序的情况下什么都不做的话,上面的路径方法也会起作用 - 在你有可选处理程序的情况下很常见,例如在GUI中。
您甚至可以使用不同的键名对同一个函数进行多次引用。您不必为单词分配功能,它们只是值。您还可以使用路径方法首先收集处理程序,保存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
该路径语法只是调用poke
的另一种方式,但有些人更喜欢它。我们必须将字符串值放在parens中,因为(希望是临时的)语法冲突,但在这些parens中,字符串键起作用。它是do select
或poke
的更快替代方案。
答案 3 :(得分:2)
尝试: .... f:选择处理程序" foo" ....