变量可变性问题
2023-03-14 22:34:36 时间
从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
相关文章
- 图解如何升级到 Linux Mint 21
- Linux 下安装使用功能强大的轻量级 HTTP 服务器
- 你需要知道的关于 Linux Mint 的一切
- 谷歌为Chrome浏览器今年的第五个 "0 day漏洞" 打补丁
- C语言在Linux内核实现面向对象的几点原因
- 40行代码实现React核心Diff算法
- 从0开始到提交PR至OpenHarmony源仓库超详细教程
- 苹果 macOS 13 Ventura Beta 5 中 TestFlight 遇到问题,无法安装或更新测试版 App
- React 中的浅比较是如何工作的?
- Fedora 37 新功能披露
- 深入了解 EPUB 文件
- HarmonyOS应用开发:鸿蒙网络管理,网络请求获取天气信息
- 在 Manjaro 和其他基于 Arch Linux 的发行版上安装 Spotify
- 如何构建 Golang Dockerfiles?
- SpringCloud—使用分布式锁实现微服务重复请求控制
- Vue2剥丝抽茧-响应式系统之NextTick
- “作弊”:只需要知道这一个 Linux 命令就够了
- 火狐浏览器 Firefox 104 发布:新增网站耗电分析工具,可自动填写地址表单
- OpenHarmony - ArkUI(TS)开发之下拉选择菜单
- Linux 下让工作效率翻倍的四个实用技巧