文档章节

scala入门之识别函数式风格

柳哥
 柳哥
发布于 2014/06/05 20:05
字数 1088
阅读 207
收藏 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
杭州
技术主管
私信 提问
加载中
请先登录后再评论。
【opencv】图形的绘制

1.矩形图像的绘制: 原函数:void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8,int shift=0) img就是需要绘制的图像 pt1 and pt......

其实我是兔子
2014/10/08
1.2K
1
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
5分钟 maven3 快速入门指南

前提条件 你首先需要了解如何在电脑上安装软件。如果你不知道如何做到这一点,请询问你办公室,学校里的人,或花钱找人来解释这个给你。 不建议给Maven的服务邮箱来发邮件寻求支持。 安装Mav...

fanl1982
2014/01/23
1.2W
7
Linux 反汇编工具--LDasm

LDasm (Linux 反汇编工具) 是一个基于 Perl/TK 的 objdump/binutils 图形化工具,试图模仿 W32Dasm 工具的外观。可搜索相互参照,将代码从 GAS 转换成 MASM 风格代码等等。...

匿名
2013/01/22
5.6K
1
REST/HTTP 工具包--Spray

Spray 是一个开源的 REST/HTTP 工具包和底层网络 IO 包,基于 Scala 和 Akka 构建。轻量级、异步、非堵塞、基于 actor 模式、模块化和可测试是 spray 的特点。 示例代码: val responses: F...

匿名
2013/02/20
7.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

创建myBatis项目

1、简介 1.1、核心组件 SqlSessionFactoryBuilder(构造器):根据配置信息或者代码生成SqlSessionFactory SqlSessionFactory(工厂接口):依靠工厂来生成SqlSession(会话) SqlSession(会话): ...

执键走天涯
昨天
5
0
Tomcat集群带来的问题和解决思路

Tomcat集群 存在问题 解决方案 基于Redis+Cookie+Jackson+Filter的原生解决集群Session共享问题 使用Spring Session零侵入解决Session共享 单点登录实现 Redis构建Session服务器 使用Redis+C...

code-ortaerc
昨天
17
0
小福利

点击有福利 本文分享自微信公众号 - V5codings(gh_c1ec2d16ec93)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

V5codings
2019/11/19
0
0
ubuntu 安装 oh my zsh

https://github.com/ohmyzsh/ohmyzsh https://ohmyz.sh/#install 安装 sudo apt-get install zsh -ysh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh ......

阿豪boy
昨天
7
0
自然语言处理中的语言模型简介

作者|Devyanshu Shukla 编译|Flin 来源|medium 在这篇文章中,我们将讨论关于语言模型(LM)的所有内容 什么是LM LM的应用 如何生成LM LM的评估 介绍 NLP中的语言模型是计算句子(单词序列)...

人工智能遇见磐创
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部