min*_*ief 1 keyword-argument argument-unpacking racket
有没有一种方法可以将函数的关键字参数指定为字典,类似于.允许我们提供位置参数列表的方法?我正在寻找类似于 python 的*args 和 **kwargs的东西。
更详细地说:
如果我们想在函数中处理任意数量的位置参数,我们可以这样定义它:
(define (my-add . args)
(apply + args))
Run Code Online (Sandbox Code Playgroud)
并将其与可变数量的参数一起使用,如下所示:
(define numbers '(1 2 3))
(apply my-add numbers) ;=> 6
(define numbers '(1 2 3 4 5))
(apply my-add numbers) ;=> 15
Run Code Online (Sandbox Code Playgroud)
即使对于没有通过.语法显式处理位置参数的“其余”部分的函数,我们也可以使用它apply从列表中解包位置参数。
(apply expt '(2 3)) ;=> 8
Run Code Online (Sandbox Code Playgroud)
我发现除了位置参数之外,apply 它还转发关键字参数。但是,只有当调用的函数本身标识了它所期望的特定关键字参数时,这才有效。例如,在分派情况下,函数本身不使用关键字参数,而只是打算将它们转发到某个适当的处理程序,以这种方式使用 apply 并不能满足我们的需要,因为函数需要了解其分派到的任何函数接受的所有关键字参数,更不用说在调用处理程序之前以某种方式重新打包它们了。
作为说明该问题的具体示例,请考虑一个简单的“echo args”函数,该函数会回显传递给它的所有参数:
(define (echo-args . args)
(printf "~a" args))
Run Code Online (Sandbox Code Playgroud)
仅使用位置参数:
> (echo-args 1 2 5)
(1 2 5)
Run Code Online (Sandbox Code Playgroud)
使用关键字参数:
> (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
Run Code Online (Sandbox Code Playgroud)
有没有内置的方法来完成这种事情?如果没有,关于如何实现这项工作有什么想法吗?
您正在寻找的是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))
Run Code Online (Sandbox Code Playgroud)
当然,作为两个列表实现的字典可能有点烦人。因此 Alex Knauth 制作了一个小包hash-lambda,它为您提供了更直接的哈希映射(如 API)。