swift 之函数式编程(一)
1. 什么是函数式编程?
函数式编程是阿隆佐思想的在现实世界中的实现, 它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及异变物件。 函数式编程的最重要基础是λ演算。而且λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值),函數式編程更加強調程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程。函数式编程的杀手锏正是当今世界上日益增长的并行性编程和元数据编程趋势。其主要思想就是把运算过程尽量写成一系列嵌套的函数调用
2. 函数式编程的特点:
- 函数是“第一等公民”:函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值
- 只用“表达式”,不用语句:“表达式”--是一个单纯的运算过程,总是有返回值; ‘语句’--执行某种操作,没有返回值。函数式编程要求,只用表达式,不使用语句,也就是说,每一步都是单纯的运算,而且没有返回值。但在实际的I/O是不可能的,因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性。
- 没有副作用:函数要保持独立,所有的功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值
- 不修改状态: 函数式编程只是返回新的值,不修改系统变量。
- 引用透明: 函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的
str就是一类不可变的数据 结构。 你不能在原来的字符串上进行修改,每次想要进行类似的操作,其实都是生成了一个新的str对象。 然而 Python 中的链表结构则是可变的。
a = "hello ,"
b = a
a += 'world'
print a # hello ,world
print b # hello ,
swift中更多的是值类型,而不是引用类型,你会发现Int,Float,String,Array,Dictionary等都是Struct类型,而Struct都是值类型【暗示了结构体应该主要 用于封装数据】,当然Enum也是值类型
在swift中区分值类型和引用类型是为了将可变和不可不区分开来。值类型的数据传递给函数,函数内部可以自由拷贝,改变值,而不用担心产生副作用。在多线 程环境下,多个线程同时运行,可能会意外错误地修改数据,这常常会是一种难以调试的bug。而使用值类型,你可以安全地在线程间传递数据,因为值类型传递 是拷贝,所以无需在线程间同步数据变化。这就可以保证代码线程环境下的安全性。
swift中的参数定义中加入inout,这样的话就可以通过参数来修改变量。这个特性很有C的风格。
使用swift自带的数据结构并不能很好的的实现“无副作用”的“纯函数式”编程。幸好作为一种关注度很高的语言, 已经有开发者为其实现了一套完全满足不可变要 求的数据结构和库:Swiftz。坚持使用let和swiftz提供的数据结构来操作,就可以实现“纯函数式”编程。
不变性有诸多好处
更高层次的抽象。程序员可以以更接近数学的方式思考问题。
更容易理解的代码。由于不存在副作用,无论多少次执行,相同的输入就意味着相同的输出。纯函数比有可变状态的函数和对象理解起来要容易简单得多。你无需再担心对象的某个状态的改变,会对它的某个行为(函数)产生影响。
线程安全的代码。这意味着多线程环境下,运行代码没有同步问题。它们也不可能因为异常的发生而处于无法预测的状态中。
惰性求值
惰性计算是函数式编程语言的一个特性。惰性计算的表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值。惰性计算有如下优点。
- 首先,你可以用它们来创建无限序列这样一种数据类型。因为直到需要时才会计算值,这样就可以使用惰性集合模拟无限序列。
- 第二,减少了存储空间。因为在真正需要时才会发生计算。所以,节约了不必要的存储空间。
- 第三,减少计算量,产生更高效的代码。因为在真正需要时才会发生计算。所以,节约那部分没有使用到的值的计算时间。例如,寻找数组中第一个符合某个条件的值。找到了之后,数组里该值之后的值都可以不必计算了。
func doSomeWork(optional:Int?,defaultValue:Int)->Int{
if let opt = optional{
return opt
}else{
return defaultValue
}
}
func doSomeWorkNew(optional:Int?, defaultValue:()->Int)->Int{
if let opt = optional{
return opt
}else{
return defaultValue()
}
}
let value:Int? = 1
doSomeWork(value, (2+5))
doSomeWorkNew(value, { () -> Int in
return 2+5
})
上面的代码可以感觉到惰性求值的好处。
swift也提供了支持惰性求值的语法:下面展示了将默认是严格求值的数组变为惰性序列:
let r = 1...3
let seq = lazy(r).map {
(i: Int) -> Int in
println("mapping \(i)")
return i * 2
} for i in seq {
println(i)
}
Swift对函数式编程的支持,使得程序员多了一种选择。Swift并不强迫程序员一定要以面向对象的方法思维。在场景合适的情况下,程序员可以选择使用函数式风格编写代码。如果确实是合适的场景,就能够改善生产力。现实的选择是支持面向对象编程的同时,提供函数式的支持。这样,在大部分面向对象游刃有余的地方,仍然可以使用面向对象的方法。而在适合函数式编程的地方,而你又拥有函数式编程的思维和能力时,还可以采用函数式的编程方法改善生产力。
接下来的系列文章中我将以《Functional Programing in Swift》这本书,来一起学习swift的函数式编程。
swift 之函数式编程(一)的更多相关文章
- swift之函数式编程
函数式编程初探 最近初学swift,和OC比,发现语言更现代,也有了更多的特性.如何写好swift代码,也许,熟练使用新特性写出更优秀的代码,就是答案.今天先从大的方向谈谈swift中的编程范式-函数 ...
- swift之函数式编程(四)
文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take func ...
- swift之函数式编程(二)
本文的主要内容来自<Functional Programming in Swift>这本书,有点所谓的观后总结 在本书的Introduction章中: we will try to foc ...
- 最通俗易懂的方式让你理解 Swift 的函数式编程
函数式编程(Functional Programming)是相对于我们常用的面向对象和面向过程编程的另外一种开发思维方式,它更加强调以函数为中心.善用函数式编程思路,可以对我们的开发工作有很大的帮助和 ...
- swift之函数式编程(三)
文章来源于<Functional Programing in Swift>,本系列仅仅是观后概括的一些内容 Wrapping Core Image 上一篇文章我们介绍了 高阶函数并且展示了 ...
- swift之函数式编程(五)
文章内容来源于<Functional Programing in Swift>,详情请看原著 The Value of Immutability swift 对于控制值改变有一些机制.在这 ...
- Swift の 函数式编程
Swift 相比原先的 Objective-C 最重要的优点之一,就是对函数式编程提供了更好的支持. Swift 提供了更多的语法糖和一些新特性来增强函数式编程的能力,本文就在这方面进行一些讨论. S ...
- swift语言的特征:类型系统与函数式编程:swift是面向类型和面向函数编程的语言
swift语言的特征: 类型系统:值类型与引用类型.泛型.协议类型 函数式编程:
- 函数式编程-将Monad(单子)融入Swift
前言 近期又开始折腾起Haskell,掉进这个深坑恐怕很难再爬上来了.在不断深入了解Haskell的各种概念以及使用它们去解决实际问题的时候,我会试想着将这些概念移植到Swift中.函数式编程范式的很 ...
随机推荐
- [js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist
promise主要是用来解决异步回调问题,其实还有好几种比promise更好的方案,后面再说,这节,我们先用promise来改造下,我以前写的一篇文章[js高手之路]javascript腾讯面试题学习 ...
- Apache CXF入门
CXF简介 Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了.CXF 继承了 Celtix 和 XFire 两大 ...
- Linux的硬盘使用情况、挂载、SSD挂载(查看df -h不能看到的卷)
linux上的盘和window的有区别,磁盘空间必须挂载在目录上,要不然没用 对与新增的硬盘.SSD固态硬盘.挂载到linux上的操作如下: df -h #显示目前在Linux系统上的文件系 ...
- 深入理解计算机系统chapter1
---恢复内容开始--- 预处理器+编译器+汇编器+链接器=编译系统 运行hello程序 操作系统: 无论是在单核还是多核系统中,一个CPU看上去都在并发的执行多个进程,这是通过处理器在进程间切换来实 ...
- LPCTSTR LPCWSTR LPCSTR 含义
#ifdef UNICODE#define LPCTSTR LPCWSTR#else#define LPCTSTR LPCSTR#endif LPCTSTR A 32-bit pointer ...
- 零复制(zero copy)技术
html { font-family: sans-serif } body { margin: 0 } article,aside,details,figcaption,figure,footer,h ...
- Java EE开发环境——MyEclipse2017破解 和 Tomcat服务器配置
Java EE开发,我们可以搭建如下开发环境: 底层运行环境:jdk 和 jre. Web服务器:Tomcat 后台数据库:SQL Server 可视化集成开发环境:MyEclipse Java EE ...
- css 浮动和清除浮动
在写页面布局的过程中,浮动是大家经常用的属性.在好多的排版布局中都是用的的浮动比如说下面这些地方都是应用到了浮动. 在我学习浮动的时候可是熬坏了脑筋,在这里我分享一下我对浮动这块知识的总结. 一.浮动 ...
- zabbix使用mysql数据库 对表分区
zabbix删除历史数据 mysql 表自动分区.删除 ----2016年终总结 二 zabbix清理历史数据是个比较蛋疼的问题,尤其在监控数据较多时,一方面无法彻底释放历史数据空间,一方面数据库删除 ...
- jquery层次选择器:空格 > next + nextAll ~ siblings
全栈工程师开发手册 (作者:栾鹏) jquery系列教程1-选择器全解 jquery层次选择器 jquery层次选择器,包括空格.>.next.+.nextAll.~.siblings等函数或表 ...