9.4.1 函数式和命令式类

在类或者类的构造函数的参数值中的 let 绑定,就像我们在其他 F# 代码中看到的 let 绑定一样,也是不可变值;此外,使用 member 关键字声明的属性,创建的是只读属性(只有 getter)。因此,如果类只引用其他不可变类型的值,那么,类也不可变。

比方说,在前面的例子中,我们要允许改变客户的收入,可以有两种方式:

■以纯函数式风格,对象将返回一个新实例,收入是更新后的,其他所有属性都是原始值。

■使用命令式风格,收入将是可变字段。

清单 9.15 展示了类的函数式版本(ClientF),以及命令式的类,名为ClassI。

清单 9.15 Client 类型的函数式和命令式版本 (F#)


type ClientF(name, inc) =

member x.Name = name   | [1]

member x.Income = inc   |

member x.WithIncome(v) =   [2]

new ClientF(name, v)

member x.Report() =

printfn "%s %d" name inc


type ClientI(name, inc) =

let mutable inc = inc    [3]

member x.Name = name

member x.Income

with get() = inc      | [4]

and set(v) = inc <- v  |

member x.Report() =

printfn "%s %d" name inc

在函数式版本中,所有属性都是只读的[1]。s 改变客户的收入,必须创建客户的一个新实例,使用 WithIncome 方法[2]很容易做到,它返回对象的副本,收入为新设置的值。

命令式版本使用 mutable 关键字[3],声明了可更新的字段,保存收入。声明字段,我们使用的名字,与值和构造函数的参数相同;新的值隐藏了原来的值,这样,我们再也不能访问原始值了。初看起来,这可能很奇怪,但是,可以防止原打算使用当前值(可能已经更改)时,而意外使用了初始值。

在命令式版本中,另一个值得注意的是用来改变客户收入的读/写属性,这个属性是由两个成员组成,类似于方法声明。get 成员没有任何参数,只返回值;而 set 成员只有一个参数,表示新值的,返回结果为 unit。虽然这个语法与 C# 属性声明略有不同,但原理相同。

当改变客户收入时,两个类的用法不同,但是,两个版本得到的结果相同。可以在清单 9.16 中看到 F# Interactive 会话,演示如何使用这两个类。

清单 9.16 Client 类型的函数式和命令式编程 (F# Interactive)

> let joeOriginal = newClientF("Joe", 30);;

val joeOriginal : ClientF

> let joeUpdated =joeOriginal.WithIncome(40);;   [1]<-- 创建客户的新实例

val joeUpdated : ClientF

> joeUpdated.Income;;

val it : int = 40

> let joeMutable = newClientI("Joe", 30);;

val joeMutable : ClientI

> joeMutable.Income <- 40;;   [2] <-- 修改已有的实例

val it : unit = ()

> joeMutable.Income;;

val it : int = 40

当使用不可变的版本时[1],我们把返回的客户值,用新的名字来保存。这样,我们仍然可以访问原始值。如果在后面的代码中,我们不想访问原始实例,就可以使用值隐藏,两个值使用相同的名字。在命令式版本中,可以使用读/写属性[2],改变收入。我们使用 <- 运算符,就像在标准的 .NET 库中使用其他声明的对象一样。

虽然我们重点在于函数式编程,但是,知道如何写这样的可变类,有时也是有用的。如果需要公开大段的 F# 代码给 C# 客户端,可能要把代码包装到至少一个类中,因为,这样更方便从 C# 中使用。在这一点上,可以随便选择一种风格:命令式风格,有一些可变类型;纯函数式风格,所有都是可变的。从 F# 的观点来看,第二种方法是更清晰的;但对于开发人员来说,不习惯于处理完全组合不可变类型的库,可能会发现使用可变状态的包装会更容易。

我们几乎准备展示从 C# 调用 F# 代码的完整示例子了,但还需要先完成面向对象的 F# 功能之旅。

时间: 2024-08-12 11:35:02

9.4.1 函数式和命令式类的相关文章

Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言

Atitit.编程语言的主要的种类and趋势 逻辑式语言..函数式语言...命令式语言 1. 编程语言的主要的种类 逻辑式语言..函数式语言...命令式语言 1 2. 逻辑式语言,,不必考虑实现过程而只需考虑定义和结果 1 3. 第五代语言 1 1. 编程语言的主要的种类 逻辑式语言..函数式语言...命令式语言 在FAQ3里说过,世界上有C和LISP两种编程语言,你现在学了C,以后学了C++.Java..NET 等等,也仍然只认识了半个世界.LISP和 Haskell构成了另外半个世 2. 逻

有用函数编程

<序> 感谢 关于本书 关于封面 第一部分 学习函数式思维 第一章 不同的思维 1.1 什么是函数式编程? 1.2 通往有用函数编程之路 1.3 用函数式编程提高生产力 1.3.1 函数范式 1.3.2 声明式编程风格 1.3.3 了解程序的执行 1.3.4 设计并发友好的应用程序 1.3.5 函数风格怎样形成代码 1.4 函数式编程演示样例 1.4.1 用声明式风格表达意图 1.4.1.1 用 LINQ 处理数据 1.4.1.2 用 XAML 描写叙述用户界面 1.4.1.3 声明式函数动画

Python的函数式编程,从入门到?放弃?

转:http://python.jobbole.com/84927/ 很早以前就听说过了函数式编程,印象中是一种很晦涩难懂的编程模式,但却一直没有去进行了解. 恰好这周组内的周会轮到我主持,一时也没想到要分享什么.灵光一闪,就选定函数式编程这个主题吧,反正组里的同事都没有学过,只需要讲解入门方面的知识就好,也正好可以借这个机会逼迫自己去学习下这种新的编程方式. 经过初步了解,发现支持函数式编程的语言挺多的,除了像Lisp.Scheme.Haskell.Erlang这样专用的函数式编程语言,我们常

函数式编程思维——互动出版网

这篇是计算机类的优质预售推荐>>>><函数式编程思维> 思维方式的跨越让你的编程能力如虎添翼 编辑推荐 Java等现代编程语言中出现了越来越多的函数式特性,跟随这本书,去了解语法表象之下真正需要掌握的新思维.中高级开发者可以从知名软件架构师Neal Ford的演示中,体会到函数式编程思想是怎样通过改换视角,让我们站在了另一个抽象层次上,把编程问题看得更加清晰. 本书每一章都会给出各种函数式编程思维的示例,并用Java 8或其他具备函数式能力的JVM语言代码实现出来.改变

Java函数式编程和lambda表达式

为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于某种语法或调用API去进行编程.例如,我们现在需要从一组数字中,找出最小的那个数字,若使用用命令式编程实现这个需求的话,那么所编写的代码如下: public static void main(String[] args) { int[] nums = new int[]{1, 2, 3, 4, 5,

Python的函数式编程

Contents 1. 目标 2. 命令式编程 & 函数式编程 3. Python函数式编程的基本单元 3.1. lambda 3.2. map() 3.3. reduce() 3.4. filter() 4. 替换条件控制语句 5. 替换循环控制语句 5.1. 替换for循环 5.2. 替换while循环 6. 更多示例 7. 总结 8. 参考链接 很早以前就听说过了函数式编程,印象中是一种很晦涩难懂的编程模式,但却一直没有去进行了解. 恰好这周组内的周会轮到我主持,一时也没想到要分享什么.灵

函数式编程工具:filter和reduce

# -*- coding: utf-8 -*- #python 27 #xiaodeng #函数式编程工具:filter和reduce #python内置函数中,map函数是用来进行函数式编程这类工具最简单的内置函数代数 #函数式编程含义: #一种编程范式,也就是如何编写程序的方法论,是一种编程思想. #无法给予准确的定义 #函数式编程的编程风格强调表达式计算,而不是执行命令. #常见函数式编程 #filter:基于某一测试函数过滤出一些元素 #reduce:对每对元素都应用函数并运行到最后结果

js17---创建对象:构造函数式和原型组合模式、动态原型模式、稳妥构造函数式

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Unt

Python面向对象之为何要用类

对于非程序员科班出身的技术人员,理解很多开发思想领域里面的事情,其实是一件挺痛苦的事情,直到接触到了Python当中的类,我才明白了什么是面向对象,更多的理解还是要通过实际的代码操练才能够慢慢的掌握. 今天记录一下什么是面向对象,在Python的编程世界里为什么要用到类. 一.面向对象 将大家共有的特性剥离出来进行抽象的过程就是面向对象,这是我对面向对象最直观的理解,例如我们在工厂生产汽车,每一款车都有自己的生产平台,试想一下这样的场景,A款车有100个工人在独立生产,其中20个人生产底盘,20