【问题标题】:Parentheses inside anonymous function with vector as parameter以向量为参数的匿名函数内的括号
【发布时间】:2011-06-01 14:02:21
【问题描述】:

我还在学习 clojure,但我有一个疑问

当我写一个匿名函数时,我会这样做

fn [parameter] 
 (do something)

好的..函数体用一组括号括起来

现在我正在阅读这样的斐波那契解决方案

(iterate (fn [[a b]] [b (+ a b)]) [0 1]))

我怀疑为什么不是这样

(iterate (fn [[a b]]  (    [b (+ a b)]   ))   [0 1]))

我用()附上函数

(iterate (fn [[a b]]   "("    [b (+ a b)]   ")"  )   [0 1]))

它接收一个向量然后返回body函数而不是其他向量...

当我使用类似参数的向量调用函数或者我犯了一个大错误时,情况就不同了。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    如果一个函数返回一个向量,你不需要用任何东西包装它,只需要返回括号中的向量。函数的主体不一定“包裹”在括号中,这很常见,因为通常函数在返回值之前会做几件事,这涉及到使用括号。

    因此,如果您只是从函数返回向量,则函数的“主体”可以是 [foo,bar,baz]。如果您要返回地图,则函数的主体可能是{:a foo, :b bar, :c baz}。如果您返回单个值,它可能是单个符号。

    括号中“包裹”的唯一内容是整个函数定义本身,无论是(fn [] ...)#(...) 还是(defn [] ...)

    进一步说明:括号和大括号[]{} 实际上分别只是(vector) 函数和(hash-map) 函数的语法糖,所以[1,2,3] 是与(vector 1 2 3) 相同,{:a foo, :b bar}(hash-map :a foo :b bar) 相同。如果它可以帮助您看到“包裹”在括号中的函数体,您可以使用较长的函数名称来返回 Clojure 的向量和映射数据类型,但使用方括号和大括号更为惯用。

    【讨论】:

      【解决方案2】:

      也许用比 Semperos 更简单的词来说,[1 2 3] 是 (vector 1 2 3) 的简写/等效,所以括号就在那里! {:a 1 :b 2} 类似,相当于 (hash-map :a 1 :b 2)。

      我没有查到什么,但是在 clojure 阅读器的源代码中挖掘可能会很有趣,看看它是否确实用 (vector ...) 替换了 [.. ] 中的任何内容,或者使用了其他一些技巧:-)。

      【讨论】:

      • 您的预感大体上是正确的... [...] 实际上是 Clojure 阅读器在阅读时应用的“阅读器宏”。它实际上并没有进行严格的搜索/替换,但它确实以与 (vector ...) 相同的方式创建了一个向量。如果您有兴趣,来源在 clojure.lang.LispReader (github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/…)!
      • 附注[] 实际上比 (vector ....) 更有效和更惯用,所以在大多数情况下你应该更喜欢 []。
      • @mikera 但是[...] 在读取时变成了向量并嵌入到代码中; (vector ...)是代码中的一个列表,只有在运行时才会变成一个向量。
      猜你喜欢
      • 2011-10-01
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 1970-01-01
      • 2018-08-16
      • 2011-03-24
      相关资源
      最近更新 更多