1

如果这是一个真正的基本问题,我很抱歉,但我看到的一些代码让我很好奇。

该函数的惯用用法是apply什么?

例如,我见过这样写的代码:

(distinct [1 2 3 4 5 6])

(apply distinct? [1 2 3 4 5 6])

这些返回相同的结果,甚至在文档中,它也清楚地表明:

;; 注意以下两种形式的等价性

用户=>(应用 str [“str1”“str2”“str3”])“str1str2str3”

用户=>(str“str1”“str2”“str3”)“str1str2str3”

这个例子是不是太基本而无法传达 的用处apply?还是我错过了两者之间的根本区别?

什么时候一种形式被认为优于另一种形式?

4

4 回答 4

5
user=> (apply str ["str1" "str2" "str3"]) "str1str2str3"

user=> (str "str1" "str2" "str3") "str1str2str3"

在这个例子中, using 的好处apply是它可以获取一个字符串列表。str,就其本身而言,不能。

我不是专家,但我的直觉告诉你,apply除非必要,否则不要使用。因此,如果您有一组要传递给可变参数函数的值,这apply很有用——否则,只需使用普通函数,例如str.

于 2013-03-20T15:05:06.377 回答
4

这些都是正确的,但出于非常不同的原因:

(distinct? [1 2 3 4 5 6])
;=> true

只有一个参数,即 1..6 的向量,它不同于任何其他参数,因为 没有其他参数

(apply distinct? [1 2 3 4 5 6])
;=> true

有 6 个参数,所有参数都是不同的。

观察:

(distinct? [1 1 1])
;=> true

只有一个参数,三个1s的向量

(apply distinct? [1 1 1])
;=> false

有三个参数,所有三个参数都是1.

注意区别:

(str [1 2 3])
;=> "[1 2 3]" -- single argument of a vector stringified

(apply str [1 2 3])
;=> "123" -- three arguments each stringified and concatenated

Apply effects 变换(apply f [a b c]) => (f a b c),这一般是一样的(f [a b c])

于 2013-03-20T15:19:18.750 回答
2

apply当您想将集合视为函数的参数时使用。如果distinct它需要一个集合作为它的参数,所以没有必要使用apply.

(distinct [1 2 3 4 1 1])
;returns: (1 2 3 4)

distinct?如果它的参数不同,则返回 true:

(distinct? [1 2 3 4 1 1])
;returns true because there's only one argument

apply使用集合中的项目作为参数:

(apply distinct? [1 2 3 4 1 1])
;returns false because of the duplicated 1's
于 2013-03-20T15:27:47.947 回答
1

通常,我apply在调用函数时将向量转换为参数。这很像 JavaScript 中的函数apply如下所示

诸如可变参数的函数str并期望与输入具有相同的类型,在这种情况下,任何实现toString. 使用(str a b c)是惯用的,(apply str [a b c])不是。

apply当您有一个异构向量,您希望将其项目用作函数的参数时,可以使用该函数。您可能会发现需要创建一个向量列表,其中向量中的项目对应于函数的参数,那么有必要使用apply.

我认为是apply:将向量分解为参数。

例子:

(def authtypes [:basic :basic :oauth])
(def usernames ["charlie" "snoopy" "lisa"])
(def passwords ["brown" "dog" "maggie"])

(let [credentials (map vector authtypes usernames passwords)]
  (doseq [c credentials]
    (apply login-user c)))
于 2013-03-20T15:27:42.117 回答