文档章节

scala入门之识别函数式风格

柳哥
 柳哥
发布于 2014/06/05 20:05
字数 1088
阅读 177
收藏 1
点赞 0
评论 0

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不是只能使用函数式风格编程的纯函数式语言。它是这两种风格的混合式语言。甚至有时你会发现指令式风格能更有效地解决手中的问题,那就使用指令式风格,别犹豫

© 著作权归作者所有

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

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

liwei2000
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
总有你要的编程书单(GitHub )

目录 IDE IntelliJ IDEA 简体中文专题教程 MySQL 21分钟MySQL入门教程 MySQL索引背后的数据结构及算法原理 NoSQL Disque 使用教程 Neo4j .rb 中文資源 Redis 命令参考 Redis 设计与实现 The ...

汇智网
2017/11/22
0
0
free-programming-books-zh.md

语言无关MySQL NoSQL PostgreSQL Web WEB服务器 其它 函数式概念 分布式系统 在线教育 大数据 操作系统 数据库 智能系统 正则表达式 版本控制 程序员杂谈 管理和监控 编程艺术 编译原理 编辑...

银月光海
2016/05/20
70
0
Scala编程语言视频教程|Scala视频教程

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

nitycka
2017/11/01
0
0
Scala 技术周刊 | 第 22 期

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

ScalaCool
2017/09/22
0
0
内建控制结构之不再使用break和continue

Scala中没有把break与continue作为关键字,scala去掉了这些命令因为它们与函数式字面量啮合得不好。Continue在while循环中的意思很清楚,但是在函数式字面量中表示什么呢?虽然scala既支持指...

柳哥
2014/06/07
0
0
Fanta/free-programming-books-zh_CN

免费的编程中文书籍索引 免费的编程中文书籍索引,欢迎投稿。 国外程序员在 stackoverflow 推荐的程序员必读书籍,中文版。 stackoverflow 上的程序员应该阅读的非编程类书籍有哪些? 中文版...

Fanta
2016/11/14
0
0
开源电子书

目录 语言无关类 操作系统 智能系统 分布式系统 编译原理 函数式概念 计算机图形学 WEB服务器 版本控制 编辑器 NoSQL PostgreSQL MySQL 管理和监控 项目相关 设计模式 Web 大数据 编程艺术 ...

zting科技
2017/12/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Confluence 6 配置时间和日期格式

你可以修改你 Confluence 为用户显示的时期和时间格式。设置的句法使用的是 SimpleDateFormat class,请参考 Java SimpleDateFormat 文档中的内容来设置日期和时间格式。 有下面 3 个时间和日...

honeymose
10分钟前
0
0
php seralize unserialize

关于PHP 序列化(serialize)和反序列化(unserialize)出现错误(Error at offset)的解决办法。 首先我们分析一下为什么会出现这个错误: 编码问题 UTF-8: ANSI: 我发现在我的机器上边编码改...

yeahlife
16分钟前
0
0
七、JSP九大内置对象和四个作用域

九大内置对象: request:类型是HttpServletRequest,和Servlet里的HttpServletRequest一模一样。 response:类型是HttpServletResponse,和Servlet里的HttpServletResponse一模一样。JSP里基...

Wakeeee_
19分钟前
0
0
第十四章NFS服务搭建与配置

14.1 NFS介绍 NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netap...

Linux学习笔记
51分钟前
0
0
双向认证-nginx

1、设置容器 docker run -it --name nginx-test2 -v /home/nginx:/apps -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro -p 8183:80 -p 7443:443 -d nginx:stable 2、修改nginx配......

hotsmile
52分钟前
0
0
深入了解 Java 自动内存管理机制及性能优化

一图带你看完本文 一、运行时数据区域 首先来看看Java虚拟机所管理的内存包括哪些区域,就像我们要了解一个房子,我们得先知道这个房子大体构造。根据《Java虚拟机规范(Java SE 7 版)》的规...

Java大蜗牛
54分钟前
4
0
SpringBoot | 第六章:常用注解介绍及简单使用

前言 之前几个章节,大部分都是算介绍springboot的一些外围配置,比如日志 配置等。这章节开始,开始总结一些关于springboot的综合开发的知识点。由于SpringBoot本身是基于Spring和SpringMvc...

oKong
54分钟前
9
0
云数据库架构演进与实践

如今,大型企业如金融企业和银行等,在下一代的微服务架构转型要求下,需要基础软件和数据平台能够实现原生的云化,以满足微服务架构的需求。 微服务,也就是一种面向服务的,有特定边界的松...

巨杉数据库
56分钟前
0
0
Linux系统梳理---系统搭建(一):jdk卸载与安装

1.去官网下载符合Linux版本的jdk,暂用jdk-8u171-linux-x64.rpm 2.登陆Linux,进入usr目录,创建java目录(方便管理,可以其他位置):mkdir java 3.上传下载的jdk包至Linux服务器,使用rz指令(sz f...

勤奋的蚂蚁
今天
0
0
Linux Kernel 4.16 系列停止维护,用户应升级至 4.17

知名 Linux 内核维护人员兼开发人员 Greg Kroah-Hartman 近日在发布 4.16.18 版本的同时,宣布这是 4.16 系列的最后一个维护版本,强烈建议用户立即升级至 4.17 系列。 Linux 4.16 于 2018 年...

六库科技
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部