Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure函数和线程宏_Clojure - Fatal编程技术网

Clojure函数和线程宏

Clojure函数和线程宏,clojure,Clojure,我对Clojure语言还很陌生 在阅读时,我发现示例#([%])。因此,我尝试如下使用它: (def test1 #([%])) (test1 5) (def test1 #(-> [%])) (test1 5) 因此,我得到以下错误: ArityException Wrong number of args (0) passed to: PersistentVector clojure.lang.AFn.throwArity (AFn.java:429) 它似乎在试图调用我想要返回

我对Clojure语言还很陌生

在阅读时,我发现示例
#([%])
。因此,我尝试如下使用它:

(def test1 #([%]))
(test1 5)
(def test1 #(-> [%]))
(test1 5)
因此,我得到以下错误:

ArityException Wrong number of args (0) passed to: PersistentVector  clojure.lang.AFn.throwArity (AFn.java:429)
它似乎在试图调用我想要返回的数组

经过一段时间的挖掘,我找到了如下解决方案:

(def test1 #([%]))
(test1 5)
(def test1 #(-> [%]))
(test1 5)
我有一些问题:

  • 为什么
    #([%])
    不起作用?我对表达式
    #([x])
    做了什么
  • 在正确的示例中,我使用了。根据其文档,它用于将参数传递给下一个函数,例如
    (>x(+1))
    。在这种情况下,我甚至没有要传递的函数*在此上下文中,下一个函数是什么?我不明白为什么它解决了我的问题

  • 问题1

    语法
    #([%])
    转化为:“创建一个函数,调用该函数时将计算表达式
    ([%])
    ,其中
    %
    是传递给函数的第一个(也是唯一的)参数”。此表达式具有函数调用的语法,
    [%]
    是要调用的函数。使用
    宏扩展
    ,您可以看到发生了什么:

    (macroexpand '#([%]))
    ;; => (fn* [p1__6926#] ([p1__6926#]))
    
    clojure中的持久性向量类是
    clojure.lang.PersistentVector
    。它们实现了arity1的
    IFn
    接口,因此您可以将向量视为将索引映射到元素的函数。但是它们没有实现arity 0,这正是您试图调用的。换句话说,您的代码不起作用:

    (def test1 #([%]))
    (test1 5) ;; ERROR
    
    但是,如果将参数0传递给函数
    [%]
    ,则返回元素:

    (def test1 #([%] 0))
    (test1 5)
    ;; => 5
    
    你看到发生了什么吗?然而,对于您正在尝试做的事情,有一个更好的方法:
    [abc]
    语法只是调用
    (vector abc)
    的糖分。所以要想得到有效的东西,你可以

    (def test1 vector)
    (test1 5)
    ;; => [5]
    
    问题2

    线程优先宏的语法为
    (->x f0 f1 f2…
    ,其中
    x
    是初始值,
    f0
    f1
    等是函数调用,它们的第一个参数被忽略,由正在通过管道传递的值替换。同样,我们可以使用macroexpand来理解:

    (macroexpand '(-> x f0 f1 f2))
    ;; => (f2 (f1 (f0 x)))
    
    但是在您的例子中,函数调用被忽略了。要分析第二个示例,我们需要使用
    clojure.walk/macroexpand all
    进行完全扩展,因为我们有嵌套的宏:

    (clojure.walk/macroexpand-all '#(-> [%]))
    ;; => (fn* [p1__6995#] [p1__6995#])
    
    尽管如此,我们也可以一步一步地看:

    (macroexpand '#(-> [%]))
    ;; => (fn* [p1__7000#] (-> [p1__7000#]))
    
    (macroexpand '(-> [p1__7000#]))
    ;; => [p1__7000#]
    

    所以要回答您的问题:
    (>[%])
    中没有下一个函数。下一个函数的数目可以是任何非负数,包括零,这是问题1的情况

    语法
    #([%])
    转化为:“创建一个函数,调用该函数时将计算表达式
    ([%])
    ,其中
    %
    是传递给函数的第一个(也是唯一的)参数”。此表达式具有函数调用的语法,
    [%]
    是要调用的函数。使用
    宏扩展
    ,您可以看到发生了什么:

    (macroexpand '#([%]))
    ;; => (fn* [p1__6926#] ([p1__6926#]))
    
    clojure中的持久性向量类是
    clojure.lang.PersistentVector
    。它们实现了arity1的
    IFn
    接口,因此您可以将向量视为将索引映射到元素的函数。但是它们没有实现arity 0,这正是您试图调用的。换句话说,您的代码不起作用:

    (def test1 #([%]))
    (test1 5) ;; ERROR
    
    但是,如果将参数0传递给函数
    [%]
    ,则返回元素:

    (def test1 #([%] 0))
    (test1 5)
    ;; => 5
    
    你看到发生了什么吗?然而,对于您正在尝试做的事情,有一个更好的方法:
    [abc]
    语法只是调用
    (vector abc)
    的糖分。所以要想得到有效的东西,你可以

    (def test1 vector)
    (test1 5)
    ;; => [5]
    
    问题2

    线程优先宏的语法为
    (->x f0 f1 f2…
    ,其中
    x
    是初始值,
    f0
    f1
    等是函数调用,它们的第一个参数被忽略,由正在通过管道传递的值替换。同样,我们可以使用macroexpand来理解:

    (macroexpand '(-> x f0 f1 f2))
    ;; => (f2 (f1 (f0 x)))
    
    但是在您的例子中,函数调用被忽略了。要分析第二个示例,我们需要使用
    clojure.walk/macroexpand all
    进行完全扩展,因为我们有嵌套的宏:

    (clojure.walk/macroexpand-all '#(-> [%]))
    ;; => (fn* [p1__6995#] [p1__6995#])
    
    尽管如此,我们也可以一步一步地看:

    (macroexpand '#(-> [%]))
    ;; => (fn* [p1__7000#] (-> [p1__7000#]))
    
    (macroexpand '(-> [p1__7000#]))
    ;; => [p1__7000#]
    

    所以要回答您的问题:
    (>[%])
    中没有下一个函数。下一个函数的数目可以是任何非负数,包括零,这是
    (>[%])

    @Rulle给出了详细的解释

    我可以指出最重要的部分吗?从
    Clojure.org
    上可以看到:

    ;; DO NOT DO THIS
    #([%])
    

    所以,不要那样做这是一个愚蠢的把戏,只会引起困惑和痛苦。你为什么要这样做?

    @Rulle对细节做了详尽的解释

    我可以指出最重要的部分吗?从
    Clojure.org
    上可以看到:

    ;; DO NOT DO THIS
    #([%])
    

    所以,不要那样做这是一个愚蠢的把戏,只会引起困惑和痛苦。你为什么要这样做呢?

    规范应该是
    #(向量x)
    。答案谢谢@leetwinski,我使用这些函数只是为了学习。本教程本身建议使用
    vector
    函数。您的主要问题将在中详细介绍。不过,我不想以重复的形式结束这篇文章,因为对
    ->
    的额外讨论很有用。规范是
    #(向量x)
    。答案谢谢@leetwinski,我使用这些函数只是为了学习。本教程本身建议使用
    vector
    函数。您的主要问题将在中详细介绍。不过,我不想以重复的形式结束这篇文章,因为关于
    ->
    的附加讨论很有用。谢谢您的支持