1.3.3 了解程序的运行

在通常的命令式风格中,程序由对象组成,对象有内部状态,既可以经直接更改,也可以通过调用对象的方法更改。这意味着当我们调用一个方法时,很难知道这个操作影响了哪个状态。例如,在清单 1.1 的C# 代码片段中,我们创建了一个椭圆,获取它的边框,在返回的矩形上调用方法,最后,返回这个椭圆给调用者。

Listing 1.1 Working with ellipse andrectangle (C#)

Ellipse ellipse = new Ellipse(newRectangle(0, 0, 100, 100));

Rectangle boundingBox =ellipse.BoundingBox;

boundingBox.Inflate(10, 10);

return ellipse;

我们怎么能知道代码运行后,椭圆是什么状态,通过看代码吗?很难,因为 boundingBox 可能是指向是椭圆的边框[ 即引用类型],Inflate 方法能够修改矩形,同时也就椭圆改变了;或者,矩形类型也许是值类型(在 C# 中,使用关键字 struct 声明),当我们把它赋值给变量时,它会被复制,这样 Inflate 方法就会不修改原来的矩形,其结果是返回一个新的矩形,因此第三行就不会有任何影响。

在函数式编程中,大部分数据结构是不可变的(immutable),这样,我们就不能修改。因此,椭圆或矩形创建以后,就不能改变了,唯一能做的就是用新建边框的方法创建一个新的椭圆。

这样,就容易了解程序的运行了,如清单 1.2 所示,如果椭圆和矩形都是不可变的,我们可以重写前面的代码段。正如你所看到的,了解程序的行为就变得更容易。

Listing 1.2 Working with immutable ellipseand rectangle (C#)

Ellipse ellipse = new Ellipse(newRectangle(0, 0, 100, 100));

Rectangle boundingBox =ellipse.BoundingBox;

Rectangle smallerBox =boundingBox.Inflate(10, 10);

return new Ellipse(smallerBox);

在用不可变类型写程序时,方法唯一能做的就是返回结果,它不能修改任何对象的状态。可以看到,由于 Inflate 方法的结果返回一个新的矩形,这样,就创建了一个新的椭圆,作为返回结果,椭圆的边框是修改后的。第一次用这种方法可能会感到有点陌生,但请记住,对于 .NET 开发人员来说,这并不是新思想。在 .NET 中,字符串可能是最著名的不可变类型,当然,还有很多例子,比如,日期时间和其他值类型。

函数式编程进一步发挥了这种思想,能够容易看到程序的运行,因为方法的结果能够完全说明方法在做什么。后面我们会详细说到不可变性,但先要讨论一个非常有用的领域:实现多线程应用。

1.3.3 了解程序的运行

时间: 2024-10-11 01:42:16

1.3.3 了解程序的运行的相关文章

程序的运行顺序[转]

关於程序的运行顺序 我们知道 Linux 是多人多工的环境,由 top 的输出结果我们也发现, 系统同时间有非常多的程序在运行中,只是绝大部分的程序都在休眠 (sleeping) 状态而已. 想一想,如果所有的程序同时被唤醒,那么 CPU 应该要先处理那个程序呢?也就是说,那个程序被运行的优先序比较高? 这就得要考虑到程序的优先运行序 (Priority) 与 CPU 排程罗! CPU 排程与前一章的例行性工作排程并不一样. CPU 排程指的是每支程序被 CPU 运行的演算守则, 而例行性工作排

linux程序后台运行

linux命令后台运行  有两种方式: 1. command & : 后台运行,你关掉终端会停止运行   2. nohup command & : 后台运行,你关掉终端也会继续运行 一. 简介     Linux/Unix 区别于微软平台最大的优点就是真正的多用户,多任务.因此在任务管理上也有别具特色的管理思想.我们知道,在 Windows 上面,我们要么让一个程序作为服务在后台一直运行,要么停止这个服务.而不能让程序在前台后台之间切换.而 Linux 提供了 fg 和bg 命令,让你轻松

MFC第一节-windows程序内部运行机制

一.窗口 设计窗口类时: 1 typedef struct _WNDCLASS{ 2 UINT style; //如水平.垂直变化是否重绘,禁用Close,检测双击 3 WNDPROC lpfnWndProc;//窗口过程函数句柄 4 int cbClsExtra;//类附加内存 5 int cbWndExtra;//窗口附加内存 6 HANDLE hInstance;//实例句柄 7 HANDLE hIcon;//图标 8 HCURSOR hCursor;//光标 9 HBRUSH hbrBa

玩转VC++实现程序开机运行及注册表修改

 一.方案 要实现Windows程序开机运行,需要在注册表中相关位置加入键值.所谓的键可以是你程序的名称,值就是你程序的所在目录.所谓的相关位置有两处: 主键HKEY_LOCAL_MACHINE,Software\Microsoft\Windows\CurrentVersion\Run下. 主键HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run下. 区别就是前者针对机器上所有用户,而后者只针对当前用户. 在编程中对

windows下python脚本程序的运行

c:\python33\python.exe c:\python33\trycoding.py windows下python脚本程序的运行,布布扣,bubuko.com

Web程序的运行原理及流程(一)

自己做Web程序的开发也有两年多了 从最开始跟风学框架  到第一用上框架的欣喜若狂 我相信每个程序员都是这样过来的 在大学学习一门语言 学会后往往很想做一个实际的项目出来  我当时第一次做WEB项目看的书是struts2 + spring + hibernate 从入门到精通 迷迷糊糊的看完了  顺着步骤一步步搭建环境  也不知道花了多久才跑通  其实框架帮我做了很多事情 我自己那个时候都不知道 现在 我建议使用框架的同时 多注意框架到底帮你做了什么 这对一个web程序员的进阶非常重要 以后也会

内存的划分 & 程序代码运行时内存工作流程

内存的划分: 1,寄存器. 2,本地方法区. 3,方法区. 4,栈内存. 存储的都是局部变量. 而且变量所属的作用域一旦结束,该变量就自动释放. 5,堆内存. 存储是数组和对象(其实数组就是对象) ,凡是new建立的都在堆中. 特点: 1)每一个实体都有首地址值. 2)堆内存中的每一个变量都有默认初始化值,根据类型的不同而不同.整数是0,小数0.0或者0.0f,boolean类型是false,char类型是 '\u0000',引用数据类型是NULL 3)垃圾回收机制. 全局变量和局部变量的区别:

关于<printf重定向到串口导致程序无法运行>的问题

摘自:http://www.openedv.com/posts/list/3172.htm usart这部分代码我也是从网上copy出来的,一下是作者的解释:简单地说:想在mdk 中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式), 标准库函数的默认输出设备是显示器,要实现在串口或LCD输出,必须重定义标准库函数里调用的与输出设备相关的函数. 例如:printf输出到串口,需要将fputc里面的输出指向串口(重定向),方法如下: #ifdef __GNU

java拾遗4----一个简单java程序的运行全过程

简单说来,一个java程序的运行需要编辑源码.编译生成class文件.加载class文件.解释或编译运行class中的字节码指令. 下面有一段简单的java源码,通过它来看一下java程序的运行流程: 1 class Person 2 3 { 4 5 private String name; 6 7 private int age; 8 9 10 11 public Person(int age, String name){ 12 13 this.age = age; 14 15 this.na

黑马程序员----整个程序的运行过程

程序的运行过程: 1.编写代码: 2.编译:把C语言代码翻译成0和1 *工具:clang编译器,(Xcode 3 gcc Xcode 4 llvm clang) *指令:cc -c 文件名.c *编译成功会自动生成一个.o目标文件 3.连接:把我们的.o目标文件和系统自带的函数库合并在一起,生成一个可执行文件 *指令:cc 文件名.o *链接成功后会自动生成一个.out可执行文件 4.运行 *指令:./a.out(./代表在当前文件夹下,a.out为生成的可执行文件) 注意: 1.cc 文件名.