您现在的位置是:首页 > 文章详情

变量可变性问题

日期:2017-05-01点击:541

从FP的角度, Clojure中变量是不可变的, 改变一个变量实际是创建一个新的变量

所以所有的change都需要通过参数的不断传递...

如下面的例子,

=> (defrecord Employee [name room]) backtype.storm.util.Employee => (def emp (Employee. "John Smith" 304)) #'backtype.storm.util/emp => (:name emp) "John Smith" => (assoc emp :room 309) #backtype.storm.util.Employee{:name "John Smith", :room 309} => (println emp) #backtype.storm.util.Employee{:name John Smith, :room 304}

Clojure是一个妥协的语言, 
不单纯的从FP的角度思考, 也需要从OO的角度思考, 你可以认为这是灵活的体现 
所以有时候, 单纯的依赖参数的传递很麻烦...虽然很pure FP

希望有变量的可变性, 将结果暂存下来, 这样无疑带来了副作用(side effects), 但提供了些便利, 尤其对习惯于oo思维的工程师

 

两种方法 ,

1. 使用java对象 
虽然说clojure变量是不可变的, 但是如果在clojure里面直接使用Java对象, 相当于跳过了clojure这层, 如下面的例子,

=> (import 'java.awt.Point) java.awt.Point => (def pt (Point. 5 10)) #'backtype.storm.util/pt => (.x pt) 5 => (set! (.x pt) -42) -42 => (.x pt) -42 

可以看到在storm里面, 仍然有大量的代码是用java实现的, 尤其是类的封装, 为什么不全用clojure? 可以思考

 

2. 当然clojure并不是没有考虑到这个问题, 他提倡的是管理可变变量

通过ref, atom, 其实是定义reference, 变量本身是不变的, 可以通过swap!将ref或atom切换到不同的变量上

=> (def test-ref (atom {})) #'backtype.storm.util/test-ref => (swap! test-ref assoc :a 1) {:a 1} => @test-ref {:a 1}
本文章摘自博客园,原文发布日期: 2013-08-16
原文链接:https://yq.aliyun.com/articles/85698
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章