2.2.1 使用不可变值

2.2.1 使用不可变值

函数程序第一个常见功能是很少儾使用典型的变量,这与我们从其他编程语言所了解不同。主要的差别在于,函数语言更喜欢用不可变的变量,即变量值一旦初始化后,就不能改变。因此,再称为“变量”就相当不合适了,函数程序员通常称为“值”。

我们用一个示例来说明,说要写一个取初始值的程序,再从控制台读两个数字,将初始值加上第一个数字,再将结果乘上第二个数字。在 C# 中,通常的做法是这样的:(我们使用几个假想的方法 GetInitialValue()、ReadInt32() 和 WriteInt32(),如果你想运行这个程序,实现也很简单):

int res = GetInitialValue();

res = res + ReadInt32();

res = res * ReadInt32();

WriteInt32(res);

我们声明变量 res 保存初始值,然后,使用从控制台读取的输入值,两次修改它。现在,我们看一下同样的代码实现,但无需修改任何变量的值:

int res0 = GetInitialValue();

int res1 = res0 + ReadInt32();

int res2 = res1 * ReadInt32();

WriteInt32(res2);

因为我们没有修改第一个变量的值,每当我们想要计算新的值(res0、res1、res2)时,就声明一个新变量。两者的主要区别在于,在第二个示例中,我们没有使用赋值运算符(在 C# 中,写作等号),在第二个示例中,唯一一次出现这个符号,是在初始化变量值的时候,但它的含义不同于赋值运算符。我们不改变现有变量的值,而是用指定的初始值,创建新的变量。

使用值,在许多方面不同于变量,因此,“值”不仅是名词上的变化,而且概念不同。基于这个原因,在本书的后面,我们都使用函数术语,但你有时可能会发现,比较变量和值是很有用的。我们还将使用“值绑定”,它表示值的声明,把这个值指定给(绑定到)符号。

用不可变值代替变量,需要我们以不同的方式去表达很多问题,我们会在 2.2.3 节再回到这个主题。现在,我们先看看不可变值与我们在第一章讨论的不可变类型的概念有怎样的关系。

2.2.1 使用不可变值

时间: 2024-08-29 12:53:49

2.2.1 使用不可变值的相关文章

F#: mutable 关键字不适宜用于结构中声明可变值

关于之前日志<F#编译器的一个Bug>,有一个问题,Set函数既然运行正常,改变的值去哪里了?以下例子做出了解答: [<Struct>] type TestStruct = val mutable _x: int new(x) = {_x = x} member this.Set(x) = this._x <- x this member this.X with get() = this._x; let a = TestStruct(2) let c() = let b =

XHR 对象实例所有的配置、属性、方法、回调和不可变值

当我们声明了一个XMLHttpRequest对象的实例的时候,使用for-in来循环遍历一下这个实例(本文使用的是chrome45版本浏览器),我们会发现在这个实例上绑定了一些内容,我把这些内容进行了一下分类: 一.配置项 也就是对xhr对象进行配置.① timeout : 配置请求超时时间.② withCredentials:是否携带发送提供凭据,在下面会进行详细的说明. 二.属性项 也就是指一些请求发送或完成过程中可能会被用户读取或使用到的一些值.① readyState:xhr的状态码.②

不要使用可变类型作为参数的默认值

class HauntedBus: """备受幽灵乘客折磨的校车""" def __init__(self, passengers=[]): ? self.passengers = passengers ? def pick(self, name): self.passengers.append(name) ? def drop(self, name): self.passengers.remove(name) ? 如果没传入 passenger

关于js中值的比较规则问题

上一篇文章提到了javascript中可变值与不可变值,如果你不知道什么是可变值和不可变值,可以先去看看那篇文章,再回来看这篇,因为这篇文章是基于可变值与不可变值讲解的. 那我就默认你知道什么是可变值与不可变值. 1.对于不可变值来说(也就是数字,字符串,布尔,null,undefined),它们是比较值是否相等,如果值是相等的那么它们就是相等的. 2.但对于可变值来说(对象,数组),它们显然比较值不太合适,因为它们的值是可以改变的,所以javascript为了避免这种情况的发生,把它们的比较规

应用程序框架实战十六:DDD分层架构之值对象(介绍篇)

前面介绍了DDD分层架构的实体,并完成了实体层超类型的开发,同时提供了验证方面的支持.本篇将介绍另一个重要的构造块——值对象,它是聚合中的主要成分. 如果说你已经在使用DDD分层架构,但你却从来没有使用过值对象,这毫不奇怪,因为多年来养成的数据建模思维已经牢牢把你禁锢,以致于你在使用面向对象方式进行开发时,还是以数据为中心. 当我们完成了基本的需求分析以后,如果说需要进行设计,那么你能想到的就是数据库表及表关系的设计,这就是数据建模.数据建模的主要依据是数据库范式设计,根据要求严格程度的递增分为

2.2.2 使用不可变数据结构

函数程序表示数据,使用数据结构,我们会在第五.七章讨论数据结构.虽然数据结构的概念通常更简单,但是,我们现在要讨论复合数据类型,比如 C# 值类型,或类.从第一章我们知道,函数编程中的数据结构是不可变的. 不可变数据结构的概念,逻辑上可以从不可变值绑定的概念推导出来.典型的数据结构包含字段声明.如果我们不可变性的概念从变量声明扩展到字段声明,就能得出一切都是不可变的.在 C# 中,不可变类字段要使用 readonly 限定符,而 F# 中所有的数据结构都是不可变的,是默认情况.F# 并不是严格的

8.2.3.1 可变状态使用引用单元

要回答这个问题,我们需要能够创建一些要捕获的状态.一个方法是用 let mutable,但是,这样,并不能运行,因为这种可变值只能用于局部,不能被闭包捕获. 第二个方法是使用引用(ref)类型创建可变值,即引用单元(reference cell)的缩写,它是能够包含可变值的小对象(实际上,声明为 F# 的记录类型).要理解引用类型的原理,我们在 C# 中定义同样的类型,可以看到,相当简单: class Ref<T> { public Ref(T value) { Value = value;}

10.25 正课第二天 流程结构

九九乘法表 蛤蟆爬井 打星星 打金子塔 //控制行数 for( int hang = 1; hang<=5: hang++){ //打印空格  每行递减,实现递减效果就可以,固定值减可变值实现 for(int j=1;j<=10-hang;j++){ sop(" "); } //打印星星 for(int lie = 1;lie<=h;lie++){ sop("*") } //这一行解决后打印换行 sopln(); } 平方根

第二节 变量 、 基本类型 、 运算符 、 表达式 、 数据 、 类型转换 、 常量

一:变量 定义:在程序运行中随时可以发生变化的量 变量声明:变量的声明只能以数字,字母,下划线,且字母不能开头,同时不能是C#中的关键字. 变量使用:变量必须先声明才能使用,变量赋值必须是对应类型,int age=true:这样就会报错. 二:常量 定义:在程序的生存期内不发生更改的不可变值 常量声明:const关键字  public const int age=10; age在程序内不会变,值一直是10: 三:内置数据类型(数值类型和非数值类型) 数值类型:分为整型和非整型 整型如下图: 非整