简体   繁体   English

有没有办法将解构绑定与 &rest 一起使用?

[英]Is there a way to use destructuring bind with &rest?

I have a function that uses &rest which returns a list of the varying amount of args to the function.我有一个使用&rest的 function,它将不同数量的参数列表返回给 function。

I open break lists up with destructuring bind (db).我用destructuring bind (db) 打开中断列表。 However, db is useful for when the number of variables are known.但是,当变量数量已知时,db 很有用。

What is the best way to break up an &rest list where the number of values vary most of the time?什么是最好的方法来分解一个&rest列表,其中值的数量大部分时间都在变化?

Here's a simple example of Trivia for pattern matching:下面是用于模式匹配的Trivia的一个简单示例:

(defun foo (&rest rest)
  (trivia:match rest
    ((list* a b c _)
     (values :got-a-b-c a b c))))
CL-USER> (foo :a :b :c :and :foo)
:GOT-A-B-C
:A
:B
:C

list* allows to pattern-match on a list of varying length. list*允许在不同长度的列表上进行模式匹配。 More precisely:更确切地说:

Both list and list* patterns check if the object is of type list, has the same length and then matches the contents to the subpatterns. listlist*模式都检查 object 是否属于列表类型,是否具有相同的长度,然后将内容与子模式匹配。 list* also checks the elements against the subpatterns, however the last pattern is matched against nthcdr of the list. list* 还根据子模式检查元素,但是最后一个模式与列表的nthcdr匹配。

https://lispcookbook.github.io/cl-cookbook/pattern_matching.html https://lispcookbook.github.io/cl-cookbook/pattern_matching.html

If you don't know the number of things you wish to bind you can't possibly solve this problem because the number of variables is unknown until runtime.如果你不知道你希望绑定的东西的数量,你就不可能解决这个问题,因为变量的数量在运行时是未知的。

So the only possible case you can solve is where the number of elements in the list is constrained in some way: in particular it needs to have a maximum number of 'interesting' elements that you want to bind variables to at one time.因此,您可以解决的唯一可能情况是列表中的元素数量以某种方式受到限制:特别是它需要具有最大数量的“有趣”元素,您希望一次将变量绑定到这些元素。 In that case you can either use a matching macro of some kind, or if your requirements are simpler just use destructuring-bind :在这种情况下,您可以使用某种匹配的宏,或者如果您的要求更简单,只需使用destructuring-bind

(defun foo (&rest args)
  (destructuring-bind (&optional (a nil ap) (b nil bp) (c nil cp) &rest extras) args
    (unless (null extras)
      (error "too many args"))
    ... use AP, BP, CP to know if one, two or three arguments were
    ... provided, and A, B, C to know what they were.
    ...))

More generally you might want a matching macro.更一般地说,您可能需要一个匹配的宏。 Another answer has already mentioned Trivia, but destructuring-match provides a case -like variant of destructuring-bind :另一个答案已经提到了 Trivia,但destructuring-match提供了一个类似casedestructuring-bind变体:

(defun foo (&rest args)
  (destructuring-match args
    ((a &optional (b 0))
     (+ a b))
    ((a b c)
     (+ a (- b c)))
    (otherwise
     (error "need between 1 and 3 arguments"))))

However the above version of foo can actually be happily be dealt with by just destructuring-bind :然而,上述版本的foo实际上可以通过destructuring-bind轻松处理:

(defun foo (&rest args)
  (destructuring-bind (a &optional (b 0) (c 0)) args
    (+ a (- b c))))

The only difference here is that you don't get to control the error case.这里唯一的区别是您无法控制错误情况。 destructuring-match is really intended for pulling apart much more complex structures in macros. destructuring-match实际上是为了分解宏中更复杂的结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有没有办法使用带参数的DataTemplate? - Is there a way to use a DataTemplate with a parameter? 如何将mysqli_stmt_bind_param用于整数,布尔值等 - How to use mysqli_stmt_bind_param for integers, boolean, etc 有没有办法在一个函数定义中提供两组其余参数? - Is there a way to provide two sets of rest parameters in one function definition? 具有必需值和空对象的参数对象分解 - Parameter Object Destructuring with Required Values and Empty Object 有没有办法使用 typedef 中的参数名称 - Is There a way to use the Parameter Names from a typedef 在ES6中,是否可以将Arrow函数用作带参数的.bind(this,…)的简写形式? - In ES6, can I use Arrow functions as short hand for .bind(this, …) with arguments? 有没有一种方法可以将函数参数用作原型中的获取器? - Is there a way to use a function parameter as a getter in a prototype? 在C#中使用参数/参数的正确方法? - The proper way to use parameters/arguments in c#? ES6对象构造嵌套参数的默认值 - ES6 Object Destructuring Default Values for Nested Parameters JAX-RS / Rest:多次设置一个参数,还是使用一个逗号分隔的参数? - JAX-RS/Rest: Set a parameter multiple times, or use a single comma-delimited parameter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM