关闭

Programming Clojure学习笔记——多重方法

8.5 何时使用多重方法 从Clojure的几个开源项目可以看出: 1. 多重方法使用极少 2. 很多多重方法都是基于类型(class)来分发 使用以下一个通用原则来决定创建函数很是多重方法: 1. 如果一个函数分支基于一种或多种类型,使用多重方法 2. 不管它是什么,当你发现它是类别,而又不是Java类或数据标签时,使用多重方法 3. 使用多重方法时,必须能够在没有多重方法定义...
阅读(656) 评论(0)

Programming Clojure学习笔记——多重方法

8.4 创建非正式类别 多重方法让你可以创建非正式类别。 举例说明,考虑一个财务应用,处理活期存款帐户和储蓄存款账户。为帐户定义一个Clojure结构,通过tag为标识这两种账户: (ns examples.multimethods.account) (defstruct account :id :tag :balance) 接下来创建两种不同的账户,由::Checking和::Sa...
阅读(820) 评论(0)

Programming Clojure学习笔记——多重方法

8.3 超越简单的分发 定义一个打印集合的方法实现: (use '[clojure.contrib.str-utils :only (str-join)]) (defmethod my-print java.util.Collection [c]      (.write *out* "(")      (.write *out* (str-join " " c))      (.wr...
阅读(598) 评论(0)

Programming Clojure学习笔记——多重方法

8.2 定义多重方法 定义多重方法使用defmulti: (defmulti name dispatch-fn) name为多重方法的名字,Clojure将针对方法的参数调用dispatch-fn来选择多重方法的一个特定的方法(实现)。 考虑前一节的my-print函数,它只有一个参数,即需要打印的东西,可以基于参数的类型选择特定的实现。因此dispatch-fn必须是一个能返回参数类...
阅读(953) 评论(0)

Programming Clojure学习笔记——多重方法

8.1 没有多重方法的生活 假定Clojure没有提供print和println方法,打印任何对象,println比print方法多输出一个换行符。我们自己构建一个通用的打印机制。 为了输出字符串,空,向量我们需要如下编写代码: (use '[clojure.contrib.str-utils:only(str-join)]) (defn my-print-vector [ob] (.w...
阅读(796) 评论(0)

Programming Clojure学习笔记——宏

7.4 宏的分类 Clojure的特殊形式通常只能通过宏来实现,满足使用宏的第二个原则,因此宏的第二个原则也称为特殊形式原则。 特殊形式有一些特殊的功能: (1) 特殊形式提供了大部分基本的流控制结构,如if和recur等 (2) 特殊形式提供了直接访问Java的途径 (3) 命名的创建和绑定都是通过特殊形式,不管是通过def定义的变量,还是通过let创建一个词法绑定,或者是通过bind...
阅读(1019) 评论(0)

Programming Clojure学习笔记——宏

7.3 使宏简单化 Clojure为宏作者提供的支持 形式                描述 foo#                在语法上被引号引起的区域内,创建一个以foo为前缀的唯一名称 (gensym prefix?)            以可选的前缀prefix创建唯一名称 (macroexpand form)        使用macroexpand-1递归展开form...
阅读(1315) 评论(0)

Programming Clojure学习笔记——宏

7.2 编写控制流宏 实现unless功能,与if相反,条件不成立时执行unless后代码。 先编写函数来实现: user=> (defn unless [expr form] (if expr nil form)) 验证一下,当表达式expr为false时正确执行 user=> (unless false (println "this should print")) this sho...
阅读(1419) 评论(0)

Programming Clojure学习笔记——宏

7.1 什么时候使用宏 使用宏的两个原则和一个例外: 原则1:不要写宏。宏很复杂而且需要仔细考虑宏展开时间和编译时间的相互影响。如果你能用一个函数替代就不要用宏。 原则2:只在当且仅当只有宏可以封装你的模式时才使用宏 例外:如果相比等效的函数,宏能使你的调用者生活变得更简单,那就用吧...
阅读(574) 评论(0)

Programming Clojure学习笔记——并发

6.5 使用Vars管理线程本地状态 当你调用def或defn创建一个动态变量时,只是创建了一个变量。 当你传一个初始值给def时,该初始值就成了def创建变量的根绑定(root binding),如: (def foo 10) 变量foo的根绑定被所有线程共享,验证如下: 当前线程中 user=> foo 10 新起的线程中 user=> (.start (Thread. (f...
阅读(572) 评论(0)

Programming Clojure学习笔记——并发

6.4 使用Agents进行异步更新 类似引用,可以使用代理(agent)包装初始状态。 (agent initial-state) 如创建counter代理包装初始计数0: (def counter (agent 0)) 可以send一个函数到agent修改agent的状态,该函数不会立即执行,而是存放到线程池的send队列中,稍后执行: (send agent update-f...
阅读(544) 评论(0)

Programming Clojure学习笔记——并发

6.3 使用Atoms进行非并发同步修改 原子(Atoms)是一种比引用轻量的同步机制。 创建原子语法: (atom initial-state options?) 这里的选项options与引用refs的选项一样 示例: 使用atom存贮当前曲目代替引用ref (def current-track (atom "Venus, the Bringer of Pease")) 同样的...
阅读(448) 评论(0)

Programming Clojure学习笔记——并发

6.2 引用和软件事务存贮 在Clojure中,大部分对象都是不可变的。当你真的需要可变数据时,你必须明确说明,如创建一个可变的引用指向可变对象: (ref initial-state) 如:(def current-track (ref "Mars, the Bringer of War")) 定义引用current-track ref包装并保护它内部的状态,控制对它内部状态的访问。...
阅读(664) 评论(0)

Programming Clojure学习笔记——并发

Clojure提供强大的并发库,由四个API组成,增强不同并发模型: 引用(refs): 管理对共享状态的并发同步修改 原子(atoms): 管理对共享状态的非并发同步修改 代理(agents): 管理对共享状态的异步修改 变量(vars): 管理线程本地状态 6.1 锁的问题 选择在什么上和在哪里加锁是一件很难的事。如果加锁出现问题,会带来一系列问题: (1) 线程之间竞争导致...
阅读(437) 评论(0)

Programming Clojure学习笔记——函数编程

5.4 再谈递归 相互递归:两个或两个以上函数之间互相调用。如: (declare my-odd? my-even?) (defn my-odd? [n]      (if (= n 0)          false          (my-even? (dec n)))) (defn my-even? [n]      (if (= n 0)          true...
阅读(564) 评论(0)
37条 共3页1 2 3 下一页 尾页
    个人资料
    • 访问:147352次
    • 积分:3355
    • 等级:
    • 排名:第12819名
    • 原创:134篇
    • 转载:47篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论