【问题标题】:How to retrieve a function from a series of functions and call it如何从一系列函数中检索一个函数并调用它
【发布时间】:2014-03-25 13:15:13
【问题描述】:

我正在尝试在 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!

任何帮助表示赞赏。

【问题讨论】:

  • ;这个也可以 foo: func [] [print "hello"] do get in system/contexts/user to-word "foo"

标签: rebol rebol3


【解决方案1】:

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"

【讨论】:

    【解决方案2】:

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

    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 中。

    您甚至可以使用不同的键名对同一个函数进行多次引用。您不必为单词分配功能,它们只是值。您还可以使用 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
    

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

    【讨论】:

    • 比@sqlab 的答案更详细一点,它有最好的方法,但没有提到如何调用函数,也没有显示原始方法的缺点。
    • 直接使用字符串作为键的路径语法非常有趣
    【解决方案3】:

    你的地图中的 foo-func 只是一个未经评估的词

    >> type? select handlers "foo"
    == word!
    

    您应该首先创建您的函数,然后减少用于创建处理程序映射的块

    handlers: make map! reduce [
       "foo" :foo-func
       "bar" :bar-func
    ]
    

    那么你的地图中有函数

    >> type? select handlers "foo"
    == function!
    

    【讨论】:

    • 我使用了 :foo-func 语法,但我完全错过了 reduce 来评估块。
    【解决方案4】:

    尝试: …… f:选择处理程序“foo” ....

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多