0

有没有办法将函数的关键字参数指定为字典,类似于.允许我们为位置参数提供列表的方法?我正在寻找类似于 python 的*args 和 **kwargs的东西。

更详细地说

如果我们想在一个函数中处理任意数量的位置参数,我们可以这样定义它:

(define (my-add . args)
  (apply + args))

并将其与可变数量的参数一起使用:

(define numbers '(1 2 3))
(apply my-add numbers) ;=> 6
(define numbers '(1 2 3 4 5))
(apply my-add numbers) ;=> 15

即使对于没有通过.语法显式处理位置参数的“其余”的函数,我们也可以使用apply从列表中解包位置参数。

(apply expt '(2 3)) ;=> 8

我看到除了位置参数之外,它apply 确实在关键字参数 s 上转发。但是,这仅在被调用的函数本身识别出它所期望的特定关键字参数时才有效。例如,在函数本身不使用关键字参数而只是打算将它们转发到某个适当的处理程序的调度情况下,以这种方式使用 apply 并不能满足我们的需要,因为函数需要知道所有被分派到的函数所接受的所有关键字参数,更不用说在调用处理程序之前以某种方式重新打包它们。

作为说明问题的具体示例,请考虑一个简单的“echo args”函数,该函数回显传递给它的所有参数:

(define (echo-args . args)
  (printf "~a" args))

只有位置参数:

> (echo-args 1 2 5)
(1 2 5)

使用关键字参数:

> (echo-args 1 2 5 #:key 'hi)
; application: procedure does not accept keyword arguments
;   procedure: echo-args
;   arguments...:
;    1
;    2
;    5
;    #:key 'hi
; Context:
;  /Applications/Racket v7.5/collects/racket/repl.rkt:11:26

有没有内置的方法来完成这种事情?如果没有,关于如何进行这项工作的任何想法?

4

1 回答 1

4

您正在寻找的是make-keyword-procedure. 这会生成一个接受所有关键字参数的过程,并且可以从字典中访问。以文档中的示例为例:

> (define show
    (make-keyword-procedure (lambda (kws kw-args . rest)
                              (list kws kw-args rest))))
> (show #:blue 3 4)
'((#:blue) (3) (4))

当然,实现为两个列表的字典可能有点烦人。因此,Alex Knauth 制作了一个小包hash-lambda,它为您提供了更直接的哈希映射,如 API。

于 2020-01-02T21:36:32.303 回答