scala函数式编程(二) scala基础语法介绍
上次我们介绍了函数式编程的好处,并使用scala写了一个小小的例子帮助大家理解,从这里开始我将真正开始介绍scala编程的一些内容。
这里会先重点介绍scala的一些语法。当然,这里是假设你有一些java或者python的基础,毕竟大部分人不会将scala当作第一门学习编程的语言。
不过这些语法知识记不住也没关系,本身语法这种东西就应该在使用中被记住。这里写这篇的目的也只是梳理一遍,方便大家对语法有个初步的印象,后面可以随时查询。
PS:所使用的版本是scala 2.11.8,那我们开始吧
一.scala两种运行方式
首先,scala有两种运行方式,分别是在交互式环境运行,以及通过脚本的方式运行。先运行一下吧,在scala安装目录下有一个bin文件夹,在这个文件夹双击scala.bat(Windows系统),就可以启动scala交互环境。当然,一般在安装scala,都会将“scala目录/bin”加入到系统的Path变量中,这个时候直接运行cmd,然后输入scala就可以了。
因为scala也是运行在jvm平台上的,所以用脚本方式的话,类似于java那样,需要先编译再执行。但是一般我们都会使用IDE来处理。通过我个人是更加喜欢idea的,只要下载免费的社区版就可以满足日常开发需求。
二.scala变量和类型
2.1 变量
首先,我们先来用一个例子来看看具体语法。在交互式环境中输出hello world。
//声明一个字符串
scala> val str = "Hello world"
str: String = Hello world
//打印
scala> println(str)
Hello world
相信大家看一眼就能明白这两行代码是干嘛的,那我就说一点看不出来的。
scala声明一个变量可以用val和var。val意为这个变量是不可变的,var意为这个变量是可变的。
scala> val num = 1; //声明一个不可变的数值型变量
num: Int = 1
scala> num = 2 //因为不可变,所以要更改时,出错了
<console>:12: error: reassignment to val
num = 2
^
scala> var num_var = 1; //声明一个可变的数值型变量
num_var: Int = 1
scala> num_var = 2; //可以改变
num_var: Int = 2
从功能上来说,类似于java的final关键字。而且scala语言倾向于让你多使用val,而少用var。
为什么呢?
因为能够更方便得使用并发,在java的并发编程中,最喜欢的就是final的变量,因为它都是不变的,随便怎么用就怎么用。而scala所支持的函数式编程,天然就适合异步和并发,所以做了这样的处理,包括scala的集合类,默认也是不可变的类型,如果要使用可变的集合,需要手动指定。
2.2 scala数据类型
说完了变量,再来说说scala的数据类型。这里直接上一张图。
这张图说明了scala的数据类型继承关系,我们先看最上面的Any类型,Any类型是所有数据类型的爸爸,在它里面定义了equals,toString这些方法,类似于java的object。这一点和java还是比较类似的。
然后接着往下看,Any又有两个字类,左边的AnyVal以及右边的AnyRef。右边的先不管,那个主要是集合那边的知识,我们只看左边的。
AnyVal又被多个数据类型继承,这些就是日常常用的一些数据类型了,可以看到和Java类似,都是Int,Double,Long这些。对了,这些数据类型,Int,Double,Long什么的,都是类,不像java,还有分int和Integer。
最后再来看看最下面的Nothing和Null吧,把这俩货搁在一块说是因为这几个概念非常容易混淆,我自己要用的时候还得去查清楚了。
- java的null(scala也可以用,不过n是小写):就是代表没有任何东西,即空。一般新建一个对象,默认值就是这货。
- scala的Nothing:所有数据类型的子类,没有具体的值可以对应到这种类型,也就是说你没法为Nothing类型赋值,包括null也不行。那可能有的小伙伴就会问了,那要这个玩意干嘛呢?一般嘛,try catch的返回值就是这种类型,还有程序exit的时候也是返回它,大概就是在不需要返回值的时候,就返回这个意思意思。
- scala的Null(注意大小写):是所有集合类的子类,这种类型只能使用null来赋值,可以说基本没什么卵用。只要知道有这么个东西就行。
三.scala面向对象编程
是的,你没看错,虽然这里是用scala来进行函数式编程,但scala也同样提供了OOP的能力,后面有很大的概率也会说到,我们就顺带着简单介绍一下吧。
还是和java中的概念类似,只不过名字稍稍有些变化。对应过来大概是这样的:
- java的interface -> scala的trait (其实trait更类似abstract class)
- java的abstract class -> 一样是abstract class
- java的class -> scala的class和object(关于class和object的区别,会在后面说)
其中,虽然说java的接口对应的是scala的trait,但trait这个东西其实和interface还是有很多不一样的,比如可以定义变量,可以直接定义方法内容等。当然,没有构造器和无法接收参数这个还是不变滴。
trait Car {
val brand: String
}
trait Shiny {
val shineRefraction: Int
}
class BMW extends Car {
val brand = "BMW"
}
//通过with关键字,一个类可以扩展多个特质:
class BMW extends Car with Shiny {
val brand = "BMW"
val shineRefraction = 12
}
接下来重点说说class和object。
在scala中,是没有static这个关键字的,那么这样一来,很多java的功能就都没法实现,比如静态方法,或者是单例模式,或者是没有main方法。这个时候,object就出现了。
每个class都可以有一个同名的object,这个object被称之为伴生对象(companion class)。class和object可以互相访问对方的私有成员(public,private这些权限访问和java是一样的)。
class Json{
}
object Json {
def toJsonObject(str:String):Unit = {
}
var a = 1
def main(args:Array[String]):Unit = {
val json = Json
json.toJsonObject("......") //不需要new对象,直接使用toJsonObject方法。
}
}
得益于object,我们可以像调用java静态方法一样地写scala代码,而这一切,都要归功于object。
因为!object里面的变量,或是方法,都是static的,这里说的static是方便有java基础的童鞋理解,scala是没有static这一个关键字的。如果要使用单例,那更简单,直接定义一个object就行了。
object Timer {
var count = 0
def currentCount(): Long = {
count += 1
count
}
}
可以这样使用:
scala> Timer.currentCount()
res0: Long = 1
接下来说个比较常用的语法糖吧,那就是object的apply方法。当一个类只有一个用途的时候,就可以用它。
scala> class Foo {}
defined class Foo
//有一个apply方法
scala> object FooMaker {
| def apply() = new Foo
| }
defined module FooMaker
//新建object,自动得就调用了apply
scala> val newFoo = FooMaker() //赋值的对象是Foo,因为调用了FooMaker()的apply
newFoo: Foo = Foo@5b83f762
看上面的代码,object是不用new出来而可以直接就用的。而用的时候,其实就默认调用了这个object的apply方法。
有没有觉得很熟悉,这其实就是工厂模式。
OK,这些就是scala里面,有关面向对象的一些基础知识,当然还有更高阶的,比如集合和多态,这些后面用到的时候再说吧。
结语
本次介绍了scala的基础变量和类型,scala默认是更加推荐使用不可变的变量,而常见的数据类型和java基本差不多,只是名字和用法上有些差别。
而在面向对象这一块上,也基本和java差不多,只要有java的基础,熟悉这部分的语法应该不是问题。
那么按我的理解来说说为什么scala会有这些改动吧。首先,scala是在java发明后才被创建出来的,其设计理念必然会比java成熟一些,所以也就会想解决一些java的缺陷,比如说java某些语法较为冗余。而scala则较为灵活一些,比如多了object,不需要每次都new一个对象,再比如有交互式环境。
其次,scala也是为了贴近于函数式编程,函数式的核心,就是编写无副作用代码。而更本质地说,就是将代码拆分模块化,各个模块各司其职,不是自己的别瞎动,自己管好自己的事,这个其实和微服务的思想是一样的。
所以scala才会默认得让变量是不可变的,就是为了尽量让代码保持不变。
OK,那今天就先说到这吧,下次再说scala语法的重头戏,集合和函数。
scala函数式编程(二) scala基础语法介绍的更多相关文章
- 大数据笔记(二十五)——Scala函数式编程
===================== Scala函数式编程 ======================== 一.Scala中的函数 (*) 函数是Scala中的头等公民,就和数字一样,可以在变 ...
- Scala实战高手****第5课:零基础实战Scala函数式编程及Spark源码解析
Scala函数式编程 ----------------------------------------------------------------------------------------- ...
- Scala函数式编程(三) scala集合和函数
前情提要: scala函数式编程(二) scala基础语法介绍 scala函数式编程(二) scala基础语法介绍 前面已经稍微介绍了scala的常用语法以及面向对象的一些简要知识,这次是补充上一章的 ...
- Scala函数式编程(四)函数式的数据结构 上
这次来说说函数式的数据结构是什么样子的,本章会先用一个list来举例子说明,最后给出一个Tree数据结构的练习,放在公众号里面,练习里面给出了基本的结构,但代码是空缺的需要补上,此外还有预留的test ...
- Scala函数式编程(四)函数式的数据结构 下
前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结 ...
- Scala函数式编程(五) 函数式的错误处理
前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结 ...
- Scala函数式编程(六) 懒加载与Stream
前情提要 Scala函数式编程指南(一) 函数式思想介绍 scala函数式编程(二) scala基础语法介绍 Scala函数式编程(三) scala集合和函数 Scala函数式编程(四)函数式的数据结 ...
- 9、scala函数式编程-集合操作
一.集合操作1 1.Scala的集合体系结构 // Scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trai.这个结构与Java的 ...
- Scala学习(一)——基础语法
Scala语言是一种面向对象语言,结合了命令式(imperative)和函数式(functional)编程风格,其设计理念是创造一种更好地支持组件的语言. 特性 多范式(Multi-Paradigm) ...
- Scala函数式编程进阶
package com.dtspark.scala.basics /** * 函数式编程进阶: * 1,函数和变量一样作为Scala语言的一等公民,函数可以直接赋值给变量: * 2, 函数更长用的方式 ...
随机推荐
- Z算法
Z算法 Z算法是一种用于字符串匹配的算法.此算法的核心在于\(z\)数组以及它的求法. (以下约定字符串下标从\(1\)开始) \(\bm z\)数组和Z-box 定义\(z\)数组:\(z_{a,i ...
- Javascript中的基本数据类型,如何判断数据类型,作用域链的理解
第一部分:Javascript中的数据类型 javascript中 基本数据类型有 五种, 数字 number 字符串 string 布尔 boolean 未定义 undefined 空值 nul ...
- Redis学习总结(六)--Redis集群伸缩
我们在上一章讲了如何创建集群,今天我们来实现下集群的伸缩. 添加节点 操作流程 1.启动节点 2.将节点加入到集群中 3.将数据槽从原来的节点迁移部分到新节点上 实践 1)准备两个新节点并启动 [ro ...
- 解决ionic 上拉加载组件 ion-infinite-scroll自动调用多次的问题
ionic 中一个上拉刷新的组件 ion-infinite-scroll,如果页面未填充满页面高度,会自动检测并无限调用多次加载更多的函数:当然,主要会导致首次调用的时候,会执行几次加载更多的函数: ...
- CocosBuilder 学习笔记(3) AnimationManager 与 ccbi 文件解析
[CocosBuilder]学习笔记目录 1. 相关的类 先介绍和AnimationManager相关的几个类: CCBSequence 时间线.有成员duration(时间线时间,默认10秒).na ...
- 前端开发-CSS语法标准
一.命名规则说明: 1.命名规则说明: 所有的命名最好都小写 属性的值一定要用双引号("")括起来,且一定要有值如class="nav",id="na ...
- GMTC 2019-前端夜话《聊聊前端工程师的成长和发展》会后简要总结
今天晚上去参加了winter主持的前端夜话:聊聊前端工程师的成长和发展圆桌论坛分享会,真的是收益颇多,这次的这个嘉宾阵容也是很有诚意的,在现在前端领域都是有一定影响力的嘉宾,嘉宾阵容也列一下: 主 ...
- zabbix设置钉钉报警
1 添加机器人 在钉钉群里面添加一个机器人 会获取到一个URL: 'https://oapi.dingtalk.com/robot/send?access_token=62be1ea97b4653b8 ...
- 2019dx#4
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 AND Minimum Spanning Tree 31.75%(1018/3206) ...
- HDU5988 - 2016icpc青岛 - G - Coding Contest 费用流(利用对数化乘为加
HDU5988 题意: 有n个区域,每个区域有s个人,b份饭.现在告诉你每个区域间的有向路径,每条路有容量和损坏路径的概率.问如何走可以使得路径不被破坏的概率最小.第一个人走某条道路是百分百不会损坏道 ...