Om.next:应用与直接传递子项

Om.next: apply vs directly passing children

Om.next wiki中有这样的示例代码(链接页面底部的代码清单):

(apply dom/ul nil
    (map person list))

由于 dom/ul 接受可变数量的参数,使用 apply 与此相比有什么好处:

(dom/ul nil (map person list))

第二种方法似乎更类似于在受支持的 vanilla React 中将数组作为 children 传递。

真题(回复评论):apply有必要吗?如果是这样,为什么后一种方法不起作用?如果不是,像示例中那样使用 apply 有什么好处?

dom/ul 的 ClojureScript 签名显然类似于 (defn ul [attrs & children] ...)。这里 children 是一个可变参数。调用者可以传入0个或多个children。因此,以下调用是有效的:

(dom/ul nil (person jack))
(dom/ul nil (person jack) (person jill))
(dom/ul nil)

现在假设您有一组要用 ul 包装的元素。该集合可能来自 (map person list),其中 returns 是一个元素序列。如果像 (dom/ul nil (map person list)) 那样调用 ul,则只有一个 child 参数被传递给 ul,并且它的类型是错误的。每个 child 应该是一个元素,但传入的是元素集合。

apply 救援。 apply 的工作是处理我们有一组参数的情况,这些参数必须单独传入。所以,(dom/ul nil (person jack) (person jill)) 等价于 (apply dom/ul nil (map person [jack jill]))apply 在这种情况下是必要的,以确保将参数传递给 ul 作为该函数所期望的。跳过 apply 不是一个选项。

在 Lisp 中,您不能传递列表或集合来代替单个可变参数并期待相同的行为。

如果您仍然这样做,集合参数将被解释为所有可变参数中的第一个。要将集合传播为函数参数,您必须使用 apply.