Scala语言编程基础
1、实验描述
- 完成Scala的基本操作,达到对Scala的基本熟悉。
- 实验时长:
- 45分钟
- 主要步骤:
- 练习Scala的基础语法
- 学习使用Scala的基本数据类型
- 学习使用Scala的函数
2、实验环境
- 虚拟机数量:1
- 系统版本:Centos 7.5
- JDK 版本:1.8.0_131
- Scala版本:2.11.11
3、相关技能
- Scala 交互式环境的使用
- Scala的语法形式
4、知识点
- Scala基础概念
- Scala交互式命令行
- Scala基础语法
- Scala数据类型
- Scala函数与类
- Scala的集合
5、实现效果
6、实验步骤
6.1Scala基本概念:Scala是一个类似于Java的多范式编程语言,集成了面向对象和函数式编程的特性。Scala的特点主要有:面向对象、函数式编程、静态类型、运行于JVM(Java虚拟机),能执行Java代码
6.2Scala交互式命令行:
6.2.1Scala有一个类似与Python 的交互式命令行,
在终端输入关键字“scala”就可以进入,前提是要安装完scala,具体安装步骤如下
6.2.1.1复制软件公共目录“/home/zkpk/tgz/”下的scala压缩包到zkpk的家目录下
[zkpk@master ~]$ cd[zkpk@master ~]$ cp tgz/scala/scala-2.11.0.tgz /home/zkpk
6.3解压并安装scala
[zkpk@master ~]$ tar xvzf scala-2.11.0.tgz
6.3.1查看scala目录
[zkpk@master ~]$ ll scala-2.11.0/
6.3.2配置scala环境变量
6.3.2.1使用vim 编辑 “/home/zkpk/.bash_profile
文件,里面追加如下所示内容,并保存.
[zkpk@master ~]$ vim /home/zkpk/.bash_profile
6.3.2.2使用source命令使,环境变量生效
[zkpk@master ~]$ source /home/zkpk/.bash_profile
6.3.2.3验证scala安装,命令行键入scala出现如图4所示即可
[zkpk@master ~]$ scala
6.3.2.4可以进行简单的算数运算,
scala> 1 + 1res0: Int = 2scala>
6.3.2.5退出时,只需要输入组合键“Ctrl +D”即可。
6.4基础语法。
6.4.1首先我们编写一个入门级的“hello world”,
使用vim编辑一个“.scala”后缀的文件。
[zkpk@master ~]$ vim HelloWorld.scala
6.4.2输入如下内容
object HelloWorld {def main(args: Array[String]) {//打印出字符串 println("Hello, world!") }
6.4.3然后在命令行编译程序。编译后会生成一个.class
后缀的同名文件,我们只需要运行这个文件就可以了
[zkpk@master ~]$ scalac HelloWorld.scala[zkpk@master ~]$ scala HelloWorldHello, World!
6.5常用的数据类型和变量, 为了方便演示,我们的操作都在scala命令行中进行
6.5.1常见的类型
数据类型 描述Byte 8位有符号值,范围:-128~127Short 16位有符号值,范围:-32768~32767Int 32位有符号值,范围:-2147483648~2147483647Long 64位有符号值,范围: -9223372036854775808~9223372036854775807Float 32位IEEE754单精度浮点数Double 64位IEEE754双精度浮点数Char 16位无符号Unicode字符,范围:U+0000~U+FFFFString 字符串Boolean 布尔值:true / falseUnit 表示没有值Null 空或空引用Nothing 每一个其他类型的子类型,包括无值Any 任何类型的超类型,任何object都是Any类型的AnyRef 任何引用类型的超类型
6.5.2值和变量
6.5.2.1命令行键入scala进入scala交互式环境
6.5.2.2可以使用var声明变量,使用val声明值(也就是常量)。如:
下所示,如果改变val声明的常量的值就会报错。
scala> val res1= 1 + 1res1: Int = 2scala>scala> var name = "zkpk"name: String = zkpkscala> name = "hello"name: String = hello
6.6函数:函数通过def定义,在Scala中,你需要为函数参数指定类型签名。函数的形式如下所示
def functionName ([list of parameters]) : [return type] = { function body return [expr]}
6.6.1Ctrl +D 组合键退出交互式环境,然后新建Test.scala类,键入如下内容并保存。
object Test { def main(args: Array[String]) { var result: Int = addOne(10) println(result) } def addOne(x: Int): Int = { return x + 1 }}
6.6.1.1上面的代码中,定义了main函数和addOne函数。前面说了,main函数是程序入口函数,每个程序都必须要有的,addOne函数接收一个Int型参数,返回加1后的值。
6.6.1.2依次编译运行程序后,会看到程序的打印结果与我们的预期相符。
6.6.2函数的定义:在函数不带参数的情况下,调用的时候可以不用写括号,函数体内如果只有一条表达式,
则可以省略函数的大括号。如下所示
object Test2 { def main(args: Array[String]) { var res: Int = addOne() var res2: Int = addOne println(res) println(res2) } def addOne(): Int = 1 + 1}
6.6.2.1执行编译运行后,会看到程序的运行结果(打印两个数字2)。
6.6.3使用下划线*部分应用一个函数,结果将得到另一个函数。Scala使用下划线表示不同上下文中的不同事物,你通常可以把它看作是一个没有命名的神奇通配符。在{
* + 2 }的上下文中。如下所示
Test3.scalaobject Test { def main(args: Array[String]) { var add1 = add(1, _:Int) # 传入一个参数,另一个一个占位 var add2 = add1(2) #此时再传入第二个参数 println(add2) # 返回两个参数累加的结果 } def add(x: Int, y: Int) :Int = { return x + y }}
6.6.4柯里化函数:就是允许函数的参数根据实际的情况扮演不同的角色。如下所示,我们可以直接传入两个参数。也可以填上第一个参数并且部分应用第二个参数。
6.6.4.1打开scala命令行键入如下内容测试
scala> def func(x:Int)=(y:Int) => x*yfunc: (x: Int)Int => Int scala> val f1 = func(10) #此时返回的是一个需要接受其余参数的函数f1: Int => Int = <function1>scala> f1(10)#此时传入其余的参数(返回结果)res1: Int = 100scala>
6.6.5可变长参数:可以向函数中传入多个同类型的参数,如下示例。
# 定义一个需要传入不定长参数,然后返回将传入的参数转换成大写的函数scala> def capaitalizeAll(args:String*)={ | args.map(_.capitalize) | }capaitalizeAll: (args: String*)Seq[String]# 此时传入两个参数scala> capaitalizeAll("hello", "world")res2: Seq[String] = ArrayBuffer(Hello, World)scala>scala> capaitalizeAll("hello", "zkpk","org")res3: Seq[String] = ArrayBuffer(Hello, Zkpk, Org)
6.7类,在类中使用def定义方法,和val关键字定义变量。方法就是可以访问类的状态函数。
6.7.1构造函数:构造函数不是特殊的方法,是除了类的方法定义之外的代码。通常可以增加一个构造函数参数,并用它来初始化内部状态
class Calculator(brand: String) { val color: String = if (brand == "zkpk") { "blue" } else if (brand == "hello") { "black" } else { "white" } // 实例方法 def add(m: Int, n: Int): Int = m + n}object Test { def main(args: Array[String]) { // 你可以使用构造函数来构造一个实例 val calc = new Calculator("hello") println(calc.color) }}
6.7.2如果子类和父类在实际上没有什么区别,那么类型别名是优于继承的。
6.7.3重载,和java中类似,示例如下。
class EvenMoreScientificCalculator(brand: String) extends ScientificCalculator(brand) { def log(m: Int): Double = log(m, math.exp(1))}
6.7.4抽象类: 定义一个抽象类,定义个方法但没有具体实现。不能创建抽象类的实例。
// 定义抽象类abstract class Shape { def getArea():Int // subclass should define this}// 扩展抽象类class Circle(r: Int) extends Shape { def getArea():Int = { r * r * 3 }}object Test { def main(args: Array[String]) { // 创建类实例 val c = new Circle(2) println(c.getArea) }}
6.8特质(Traits: 特质是一些字段和行为的集合,可以扩展或混入我们的类中,class
可以扩展多个traits(使用关键字 with)。
6.9集合,Scala提供了常用的集合,包括:列表(List),集合(Set),映射(Map),选项(Option),元组(Tuple)
object Test { def main(args: Array[String]) { val x1 = List(1, 2, 3, 4) val x2 = Set(1, 3, 5) val x3 = Map("one" -> 1, "two" -> 2) val x4 = (2, "two") // 定义元组 val x5:Option[Int] = Some(5) // 定义选项 println(x1) println(x2) println(x3) println(x4) println(x5) }}
7、总结
本次实验对scala的基本概念和使用语法有了深入的了解,为我们之后的使用和学习Spark打下了坚实的基础。