变量可变性问题

简介:

从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
目录
相关文章
|
6月前
|
存储 C语言
引用共用体变量的方式
引用共用体变量的方式
74 2
|
1月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
55 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
6月前
|
存储 C语言
变量和常量的例子
变量和常量的例子
43 1
常量引用的概念
常量引用的概念
41 0
|
开发工具 索引 Python
可变对象与不可变对象
前阵子我们聊了下函数的参数传递以及变量赋值的一些内容:关于函数参数传递,80%人都错了。
|
存储 编译器 C#
C#变量与常量的区分和总结
C#变量与常量的区分和总结
|
存储 编译器 C#
【C#基础】C# 变量与常量的使用
编程语言 C# 变量和常量的介绍。
157 0
【C#基础】C# 变量与常量的使用
|
存储 编译器
常量与变量的区分
常量与变量的区分
常量与变量的区分
|
存储 编译器 程序员
【C++Primer】第2章:变量和基本类型
【C++Primer】第2章:变量和基本类型
107 0
【C++Primer】第2章:变量和基本类型
|
存储 缓存 安全
可变对象和不可变对象
编程语言的对象可变性是值得研究探讨的内容,本文试分析一下可变对象和不可变对象。
76 0