【问题标题】:Questions about Vars Clojure关于 Vars Clojure 的问题
【发布时间】:2015-09-06 17:02:04
【问题描述】:

我是 Clojure 的新手,我读到它是一种函数式语言。它说Clojure没有变量,当我找到(def n 5)时,它和变量有什​​么区别?

之后我可以更改 var 的值,那么它与变量真的有那么不同吗?我不明白其中的区别。

【问题讨论】:

    标签: clojure functional-programming


    【解决方案1】:

    def 视为定义常量。可以通过再次调用 def 来更改它,但你 should not do it

    变量的关闭是agents,它是线程安全的。

    (def counter (agent 0))
    (send counter inc)
    @counter
    ;;=> 1
    

    您也可以在 Java 类中访问该变量。

    新课程

    (def object (ClassName.))
    

    硒值

    (.fieldName object)
    

    设定值

    (set! (.fieldName object) 5)
    

    没有变量的“全部”点是使程序自动线程安全。这是因为线程错误将“总是”失败,线程 1 会告诉变量 a 为 1,线程 b 告诉变量 a 为 2,然后出现故障。这也是使用纯函数的原因——没有变量“没有”线程问题。

    另请参阅此question:Clojure differences between Ref, Var, Agent, Atom, with examples 和此Clojure: vars, atoms, and refs (oh my)

    将“”视为 80% 或更多,而不是 100%。

    【讨论】:

      【解决方案2】:

      Clojure 没有变量是不正确的,即。 e.可变参考。但是,它们不用于在可以建模为纯数学函数的计算过程中存储和查找。

      不变性的概念是处理具体值而不是一个或其他可以更改的引用。就像1 是一个您无法更改的值一样,在Clojure 中,向量[3 2] 是您也无法更改的值。例如。如果您的算法需要将1 附加到该向量,则它需要创建一个新向量,使旧向量保持原样,而在命令式语言中,您可以“更改”该向量,从而破坏可能依赖它的所有内容。不变性的好处是您不必再担心这一点,并且您的代码更不容易出错。

      Clojure 实现不可变数据结构的方式是,这些新创建的值可以有效地重用它们所基于的值的大部分内存。它们在读写(即创建新版本)方面提供了与可变对应物几乎相同的性能特征。您可能想了解更多关于 here 的信息,Rich Hickey 在与 Brian Beckmann 的对话中对 this 做了一些出色的解释。

      【讨论】:

        【解决方案3】:

        假设variable 指的是可变存储位置,我想主要区别(取决于您比较的语言)是,如果您动态重新绑定var in Clojure 是基于每个线程的。

        但长的答案是,除非您确实需要对可变存储位置的引用,否则您通常不会在 Clojure 中使用 var

        Clojure 支持不变性和使用而不是引用进行编程。

        你可以看Rich Hickey's talk关于价值观。

        总结一下,当您在 Clojure 中编程时,您所拥有的是 values ,而不是对可能更改的位置的引用(甚至可能被另一个线程更改)。

        所以。

        (let [a 1 
              _ (println a) => prints 1
              a 2 
              _ (println a) => prints 2
             ]) 
        

        即使您在该代码中产生“更改a”的错觉,您并没有更改“旧”a,您只是有一个新值。 (如果有人会查看第一个定义,它仍然会看到值 1)。

        实际上,您可以将分配序列视为组合函数调用,其中a 在范围内被替换,但根本不是同一个“变量”。

         ((fn [a]
            (println a) => prints 1
            ((fn [a]
                (println a) => prints 2
              ) 2) 1)
        

        不过,如果您需要一个可变存储,并且可能有许多线程访问该存储,Clojure gives youvarsatomsrefs 等。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-10
          • 1970-01-01
          • 1970-01-01
          • 2011-03-28
          • 2010-11-10
          相关资源
          最近更新 更多