文档章节

scala入门之识别函数式风格

柳哥
 柳哥
发布于 2014/06/05 20:05
字数 1088
阅读 181
收藏 1

scala允许指令式的编程风格,但是鼓励采用函数式的风格。如果你是从指令式的背景转到scala来的-----例如,如果你是Java程序员------那么学习scala将面对的主要挑战就是理解怎样用函数式的风格编程。我们的首要工作是识别这两种风格在代码上的差异。大致可以说,如果代码包含了任何 var 变量,那它可能就是指令式的风格如果代码根本就没有 var ------就是说仅仅包含 val ------那它或许是函数式的风格。因此向函数式风格转变的方式之一,就是尝试不用任何 var 编程。
如果你来自于指令式的语言环境,如:Java、C++、或者C#,你或许认为 var 是很正统的而 val 比较特殊。相反,如果你来自于函数式语言环境,如:Haskell、OCamel或Erlang,或许你会认为 val 很正常而对 var 就有一种抵触情绪了。然而在scala看来,val 和 var 只不过是工具箱里两种不同的工具。它们都很有用,没有一个天性邪恶。scala鼓励你学习 val ,但最终做到“物尽其用”的原则。
指令式风格的例子:

def printArgs(args:Array[String]):Unit = { 
    var i = 0
    while(i < args.length){ 
        println(args(i)) 
        i += 1
    } 
}

你可以通过去掉 var 的办法把这个代码变得更函数式风格,如例:

def printArgs(args:Array[String]):Unit = { 
    for(arg <- args) 
        println(arg) 
}

或者:

def printArgs(args:Array[String]):Unit = { 
    args.foreach(println) 
}

这个例子说明了减少使用 var 的一个好处。重构后(更函数式)的代码比原来(更指令式)的代码更简洁、明白,也更少有机会犯错。scala鼓励函数式风格的原因,实际上也就是因为函数式风格可以帮助你写出更易读懂,同样也是更不易犯错的代码。
当然,这段代码仍有修改的余地。重构后的printArgs方法并不是纯函数式的,因为它有副作用(副作用?计算并返回结果之外的其它行为??)------本例中的副作用就是打印到标准输出流。识别函数是否有副作用的地方就在于其结果类型是否为Unit。如果某个函数不返回任何有用的值,也就是说如果返回类型为Unit,那么这个函数唯一能产生的作用就只能是完成某种副作用。而函数风格的方式应该是定义对需打印的arg进行格式化的方法,不过仅返回格式化之后的字符串,如例:

def formatArgs(args:Array[String]) = args.mkString(“\n”);

现在才是真正函数式风格的了:完全没有副作用或 var 的 mkString方法,能在任何可枚举的集合类型(包括数组,列表,集和映射)上调用,返回由每个数组元素调用mkString,并把传入字符串做分隔符组成的字符串。当然,这个函数并不像printArgs方法那样能够实际完成打印输出,但可以简单地把它的结果传递给println来实现:

println(formatArgs(args));

每个有用的程序都会有某种形式的副作用,否则就不可能向程序之外提供什么有价值的东西。我们提倡无副作用的方法是为了鼓励你尽量设计出没有副作用代码的程序。这种方式的好处之一是可以有助于你的程序更容易测试。举例来说,要测试前面给出的任何一个有副作用的printArgs方法,你将需要重定义println,捕获传递给它的输出,再检查结果。相反,对于formatArgs来说你可以直接检查它的返回结果:

val res = formatArgs(Array(“zero”,“one”,“two”);
assert(res == “zero\none\ntwo”);

不过还是要牢记:不管是var还是副作用都不是天生邪恶的。Scala不是只能使用函数式风格编程的纯函数式语言。它是这两种风格的混合式语言。甚至有时你会发现指令式风格能更有效地解决手中的问题,那就使用指令式风格,别犹豫

© 著作权归作者所有

共有 人打赏支持
柳哥
粉丝 206
博文 405
码字总数 347782
作品 0
杭州
技术主管
私信 提问
Scala入门-大数据云计算下的开发语言

Scala编程语言抓住了很多开发者的眼球。如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的 面向对象编程语言,而又无缝地结合了命令式编程和 函数式编程风格。Christopher Diggins认为:...

liwei2000
2018/06/30
0
0
Scala基础入门-1

首先需要Scala开发环境的搭建,网上自己找教程。 声明常量与变量 val foo = 0 // 常量var bar = 0 // 变量    在Scala中,更加鼓励使用val来进行声明,也就是推荐使用常量。在大部分时候不...

wei-spring
2015/11/08
0
0
Spark入门到精通视频学习资料--第一章、Scala基础与实践

第一章、Scala基础与实践(3讲) Scala编程语言抓住了很多开发者的眼球。如果你粗略浏览Scala的网站,你会觉得Scala是一种纯粹的面向对象编程语言,而又无缝地结合了命令式和函数式的编程风格...

dongzhumao
2015/02/06
0
0
Scala 技术周刊 | 第 22 期

这里有最新的 Scala 社区动态、技术博文。 微信搜索 「scalacool」关注我们,及时获取最新资讯。 深度阅读 Status of the Collections Scala 集合重构进展 Akka 系列(十):Akka 集群之 Ak...

ScalaCool
2017/09/22
0
0
Scala编程语言视频教程|Scala视频教程

Scala编程语言视频教程 分享网盘下载——https://pan.baidu.com/s/1kUFL6Ub 密码: m7k4 Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于...

nitycka
2017/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

node调用dll

先安装python2.7 安装node-gyp cnpm install node-gyp -g 新建一个Electron-vue项目(案例用Electron-vue) vue init simulatedgreg/electron-vue my-project 在package.json中的scripts里添......

Chason-洪
4分钟前
0
0
Linux系统快速查找文件的技巧

Linux常用命令中,有些命令可以帮助我们查找二进制文件,帮助手册或源文件的位置,也有的命令可以帮助我们查找磁盘上的任意文件,今天我们就来看看这些命令如何使用。 which which命令会在P...

Linux就该这么学
6分钟前
0
0
dotConnect for Oracle入门指南(八):通过OracleCommand类使用存储过程

【下载dotConnect for Oracle最新版本】 dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技术上,为基于Oracle数据库的应用程序提供完整的解决方案。它为设计应用程序结构带来了新的...

电池盒
7分钟前
0
0
JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript 之间转换

摘要: 深入JS系列15。 原文:深入类和继承内部原理 + Babel和TypeScript 之间转换 作者:前端小智 Fundebug经授权转载,版权归原作者所有。 这是专门探索 JavaScript 及其所构建的组件的系列...

Fundebug
17分钟前
0
0
js 引用传值问题踩坑

先自测一下,答案在最下边。 <html><head><script type="text/javascript" src="/jquery/jquery.js"></script><script type="text/javascript">$(document).ready(function(){$("button......

S三少S
28分钟前
11
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部