Racket类中的动态函数调用与apply相结合

时间:2019-03-10 00:33:24

标签: scheme racket

TL; DR

我正在寻找的是功能send/applydynamic-send的组合。这样它就可以基于符号找到对象的方法,并且解压缩参数列表。

背景和更多信息

对于一个学校项目,我通过Racket的tcp-connect通过网络发送一些“命令”。在接收器端,此命令应从类执行方法并传递其参数。

考虑以下收到的“消息”:

(define message (list 'set-switch! '3 'on))
(define method-name (car msg))  ;'set-switch!
(define parameters (cdr msg))   ;(list '3 'on)

以及以下课程:

(define light%
  (class object%
    (super-new)

    ...

    (define/public (set-switch! id mode)
      (vector-set! switches id mode))))

现在的问题是执行此语句时

(dynamic-send light-class method-name parameters)

它完美地找到了方法set-switch!,但是它只用一个参数(list '3 'on)来调用它。

球拍docs为类提到了这三个功能:

  • (send obj-expr method-id arg)仅执行对象的方法
  • (send/apply obj-expr method-id arg-list-expr)执行一个方法并解压缩参数列表
  • (dynamic-send obj method-name v)基于符号找到方法名称

我认为我需要的是类似(dynamic-send/apply obj method-name arg-list-expr)的东西,它结合了上面提到的最后两个。

注意:我知道我可以简单地接受列表作为参数,并在函数本身中使用carcdr来获取正确的值。但这不是我想要的。

1 个答案:

答案 0 :(得分:2)

dynamic-send是一个函数(也称为过程;例如carvector-set!+),因此可以使用apply

(apply dynamic-send light-class method-name parameters)

或者甚至简单地:

(apply dynamic-send light-class message)

send具有send/apply变体的原因是send是一种形式(也称为语法;例如letdefine,{ {1}}),因此if不起作用,因此单独提供了apply