• 变量可变性问题


    从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}
  • 相关阅读:
    您所熟悉的软件测试类型都有哪些?请试着分别比较这些不同的测试类型的区别与联系(如功能测试、性能测试……)
    你对测试最大的兴趣在哪里?为什么?
    LoadRunner分为哪三个模块?请简述各模块的主要功能。
    Django学习之视图层
    Django学习之路由层
    Django学习
    Django简介
    jQuery
    JavaScript--DOM,BOM
    前端基础之JavaScript
  • 原文地址:https://www.cnblogs.com/fxjwind/p/3262270.html
Copyright © 2020-2023  润新知