这里写目录标题
前言
不得不说,作为优秀的大数据开发工程师,Scala这门语言是必须掌握的,像Spark、Flink、Kafka等底层都是Scala写的,没办法,而且近来需要使用Scala编程Spark程序,正好自身掌握的最好的语言就是Python,想一招鲜吃遍天是不太可能的,这远远不够用,学习一门新的语言已经迫在眉睫。给自己定个小目标,10天吧,10天的时间入门就行,后续在深入研究。
基础类型
两种特殊类型对象
Scala有两个特殊类型对象,一种是val,另一种是var。它们有什么区别呢?看一看编程的时候就知道了。
学过python,上来就是x=1,这不就是变量吗?,结果程序就报错。很难受,python好简单就定义了。。。想python的第一天。
python定义一个x真方便
上面控制台告诉我,错误,正在重新分配val,那么val是啥?
var是啥?
我们下来继续摸索,定义一个val变量
看上去好像是正常的,那我们修改一下试试?
val变量好像修改不了?python好像直接就改了。还是python简单。。。。
那val到底是啥?稍等,我们定义一个var变量看看。
请注意scala的代码结尾处有没有分号程序都能分清楚
然后我们修改一下看看。
似乎到这里好像已经清楚了吧。
val是定义的常量、var定义的是变量
似乎很简单就搞懂了Scala类型????
肯定是不对的,这里有一个Int 说明数据类型肯定不止var 和val这两种。相信Scala大家有所耳闻,好像自带类型推断??这应该就是数据类型推断的。
下面解释一下输出结果是说明。
res5表示变量名,而冒号( : )右边就是类型。然后赋值为2。这里有点问题,为啥没有输出变量x?这不是x变量吗?为啥是res5这个变量呢?
再后续的输入中,不断的输入控制器打印的变量名,程序会一直输入?
定义指定类型变量
我们都知道python的基本数据类型就是什么int、str、float。基本上我们定义数据类型就是直接定义,那Scala如何指定类型呢?
Scala天生就是有自动的类型推断,如果想像python一样使用的话,就是使用var这种类型,Scala会自动推断数据类型。
是不是很简单?那如何强制指定数据类型呢?
刚才已经说了看数据的类型是在冒号的右边,因此定义的时候,就要在变量名的右边使用同样的方法去定义。
注意,Scala是一切皆对象。下面这样都是错的。
交互式下Scala输错了怎么办?
如果发现了一下错误,而解释器仍然在等着更多的输入,可以通过按两次回车键取消。注意,如果想在解释器跨行输入语句的话,只要一行行写进去即可。如果输到行尾还没有结束,解释器将在下一行回应一个竖线。
定义一个函数
注意Scala解释器在定义一个函数的时候必须指定参数的类型,因为解释器无法推断出来参数的类型。注意Scala函数在递归调用的时候也必须指定返回值类型。注意返回值与python不同,Scala是有默认返回值的,默认返回只是当前函数内部最后一次计算得到结果。如果返回值为Unit则不会返回。可以强行显示返回,但是与Scala的函数式编程相违背。
数组
数组初始化
Scala定义数组的方式可是是这样的。
val greetString = new Array[String](3)
Scala也支持显式定义数据类型
val greetString: Array[String] = new Array[String](3)
Python定义数组最简单
x = []
想丢什么就丢什么进去。哈哈
这里可能会问,为什么要定义不可变类型val。因为val定义变量,那么这个变量是不能被重新赋值的。但是变量指向的对象内容,也就是存放数据的地方却是可以改变的。所以,这里变量名不能赋值成别的数组,它永远指向初始化时指定的那个Array[String]实例,但是Array[String]的内部元素始终能被修改,因此数组本身是可以变的。
那Scala有没有简单的方法定义呢?
当然,只要愿意深入了解它呢,它就确实有
val string = Array("hello","world")
确实,看起来差不多,这python转换到Scala好像也不难呢?
这里还有一种初始化数组的方式,注意apply方法可以有不定个数的参数
val string = Array.apply("hello","world")
访问数组
注意python访问数组是[]中括号,Scala是小括号
注意Scala的所有通过括号访问数组内值的方式,实际上都是对apply方法的调用。于是使用greetString(0)的访问转换为greetString.apply(0)的方式,实际上效果是一样的。这个原则不针对数组,任何对于对象的值参数应用都被转换为apply方法的调用。当然前提是这个类型实际上定义过apply方法。
修改数组内部的值
常见的修改是直接根据索引的位置进行修改,例如
实际上,Scala的数组通过索引的方式修改数组内部的值其实就是调用对象的update方法,参数分别是索引和新的赋值
例如
突然感觉和python的字典很像?好像字典也是可以这样修改的。
数组追加内容
加在数组前面
加在数组后面
注意所有的操作都是会返回一个新的对象
不可变数组
既然,数组内部的值可以修改,那肯定存在不可以修改的数组吧。python肯定没有什么不可变数组的,那Scala可能有吧。正巧List对象就是属于不可变数组。
定义一个List对象,然后分别访问数组的内容,尝试修改数组内容,解释器报错。显然Scala存在不可变的数组
不可变数组的合并(extend)
我们都知道python数组的合并是通过extend()方法合并的。
那Scala 的列表是怎么合并呢?
:::三个冒号即可实现叠加功能。注意这里返回的列表是一个新的对象
组合元素到最前端(append)
这个标题的意思就是python的append方法在Scala中的实现。请注意,append方法不是Scala的方法。如何在Scala中实现呢?其实很简单,就是 ::即可。
由于::的作用是指将列表的元素组合到现有列表的最前端,然后返回作为执行结果的新列表,请注意,这并不是原地操作,是会返回一个新的对象列表。python的append是追加到列表尾部,而Scala的列表是追加到列表的首部,而且返回一个新的对象
只能往前追加,不能往后追加
如果觉得::使用起来没有python好用,那么我们可以用python的方式追加,只不过这个方法是往前插入
one. :: (0)
Nil空列表
Nil 是空列表,我们如果用cons操作符(::)即可以将数字连接起来并产生新的列表。
1::2::3::Nil
List列表常用操作
元组
scala定义一个元组和python差别并不大,也就是多了一个对象类型而已
由于List中的数据类型一样,可能会有一些不方便的地方。那元组就可以定义不同的数据类型。例如下面
访问元组内容
python访问元组的方式和访问数组的方式一样,都是 通过中括号来访问的,不同的是Scala是通过下划线访问,这里有很大的不同
注意Scala的元组仅支持到22位。
集合
定义一个set和python很像
var jetSet = Set("Boeing","Airbus")
注意,这里我们使用的是类型推导中的自动推导,默认是可变的,不可变的最简单的方法就是 val
然后修改内容,因为我们使用的是不可变对象。默认是自动的类型推导。
提示我们导入的包是不可变的set
那么如何修改为可变的对象呢?最简单的方法就是把val修改为var
我们看看这样是不是正确的
红线没有了
内容也加进去了。那么问题如何在定义不可变类型的同时,又可以修改它呢。其实只要我们对不可变的集合,修改为导入的可变的集合即可。就是不让Scala解释器使用自己的类型推导。我们试试看看可不可以
结果也正确,确实可以这样手动修改。
集合添加元素
jetSet+="Lear"
集合删除元素
jetSet-="Lear"
字典
注意Scala的字典和python的字典是不太一样的。尽管底层原理相似,但是使用起来差异比较大。
在Scala中定义一个字典
var treasureMap = Map[Int,String]()
在python中定义一个字典
dicts = dict()
字典添加值
Scala的Map添加值
treasureMap += (1 -> "hello,word")
这里右括号的1表示字典的key,hello,world表示value。和python的字典差别还是有的。
字典访问
感觉和python的字典还是很像的,也就是定义字典,往里边加值的时候很不一样。
循环
python的循环是这样的
for i in range(10):
print(i)
Scala的循环是这样的
for (i<- 0 to 10):
println(i)
退出编译器
:q或者 :quit