scala 的介绍

来源:互联网 发布:贴吧顶贴软件 谭队 编辑:程序博客网 时间:2024/05/16 17:32

刚接触Scala 对这门语言不是很了解,简单写了一下关于Scala的一些基础知识。

Scala 是一种把面向对象和函数式编程理念加入到静态类型语言中的语言,可以把 Scala 应用在很大范围的编程任务上,无论是小脚本或是大系统都是用 Scala 实现。Scala 运行在标准的 Java 平台上,可以与所有的 Java 库实现无缝交互。可以用来编写脚本把 Java 控件链接在一起。

Scala 程序会被编译为 JVM 的字节码。它们的执行期性能通常与 Java 程序一致。Scala 代码可以调用 Java 方法,访问 Java 字段,继承自 Java 类和实现 Java 接口。实际上,几乎所有 Scala 代码都极度依赖于 Java 库。

Scala 极度重用了 Java 类型,Scala 的 Int 类型代表了 Java 的原始整数类型 int,Float 代表了 float,Boolean 代表了 boolean,数组被映射到 Java 数组。Scala 同样重用了许多标准 Java 库类型。例如,Scala 里的字符串文本是 Java.lang.String,而抛出的异常必须是 java.lang.Throwable 的子类。

Scala 的语法避免了一些束缚 Java 程序的固定写法。例如,Scala 里的分号是可选的,且通常不写。Scala 语法里还有很多其他地方省略了。例如,如何写类及构造函数,示例如下所示分别采用 Java 和 Scala。

//Java 代码class MyClass {  private int index;  private String name;  public MyClass(int index, String name) { this.index = index; this.name = name;  } }//Scala 代码class MyClass(index: Int, name: String)

Scala 有两种类型的变量,val 和 var。val 变量的值只能初始化一次,再次赋值会发生错误,var 和 Java 的变量相同,可以随时修改。val 是函数式编程的风格,变量一旦赋值就不要再做修改。

scala> val message = "hellp world"message: String = hellp worldscala> val test = "1"test: String = 1scala> test ="2"<console>:8: error: reassignment to val test ="2" ^scala> var test1="1"test1: String = 1scala> test1="2"test1: String = 2

在 Scala 里,定义方法采用 def 标示符,示例代码如下所示。

scala> def max(x: Int, y: Int): Int = if(x < y) y else x max: (x: Int, y: Int)Intscala> max(3,8)res0: Int = 8

注意,离开 Scala 编译器可以用:quit 或:q 命令。

与 Java 一样, 可以通过 Scala 的名为 args 的数组获得传递给 Scala 脚本的命令行参数。Scala 里,数组以零开始,通过在括号里指定索引访问一个元素。所以 Scala 里数组 steps 的第一个元素是 steps(0),而不是 Java 里的 steps[0]。清单 13 所示代码编写了一个 Scala 文件,定义读入第一个参数。

清单 13. 定义 Main 函数参数
[root@localhost:4 bin]# ./scala hello.scala zhoumingyaoHello, world, from a script!zhoumingyao[root@localhost:4 bin]# cat hello.scalaprintln("Hello, world, from a script!"+args(0))//Java 代码System.out.println("Hello, world, from a script!"+args(0));

当我们需要执行循环的时候,While 是一个不错的选择。

Scala 里可以使用 new 实例化对象或类实例,通过把加在括号里的对象传递给实例的构造器的方式来用值参数化实例。例如,清单 15 所示代码的 Scala 程序实例化 java.math.BigInteger,实例化字符串数组。

清单 15. 实例化参数
val big = new java.math.BigInteger("12345")val greetStrings = new Array[String](3)greetStrings(0) = "Hello"greetStrings(1) = ", "greetStrings(2) = "world!\n"for(i <- 0 to 2) print(greetStrings(i))[root@localhost:4 bin]# ./scala hello.scalaHello, world!

从技术上讲,Scala 没有操作符重载,因为它根本没有传统意义上的操作符。取而代之的是,诸如+,-,*和/这样的字符可以用来做方法名。

Scala 的 List 是不可变对象序列。List[String] 包含的仅仅是 String。Scala 的 List、Scala.List。不同于 Java 的 java.util.List,总是不可变的,在 Java 中是可变的。

val oneTwoThree = List(1, 2, 3)

List“:::”的方法实现叠加功能,程序如清单 16 所示。

清单 16. 叠加方式代码
[root@localhost:4 bin]# cat hello.scalaval oneList = List(1,2)val twoList = List(3,4)val combinedList = oneList ::: twoListprintln(oneList + " and " + twoList +" and " + combinedList)[root@localhost:4 bin]# ./scala hello.scalaList(1, 2) and List(3, 4) and List(1, 2, 3, 4)

初始化新 List 的方法是把所有元素用 cons 操作符串联起来,Nil 作为最后一个元素。

清单 17. Nil 方式
val oneTwoThree = 1 :: 2 :: 3 :: Nil println(oneTwoThree) [root@localhost:4 bin]# ./scala hello*List(1, 2, 3)

Map 是 Scala 里另一种有用的集合类。Map 的类继承机制看上去和 Set 的很像。scala.collection 包里面有一个基础 Map 特质和两个子特质 Map:可变的 Map 在 scala.collection.mutable 里,不可变的在 scala.collection.immutable 里。

清单 19. Map 操作代码
import scala.collection.mutable.Map val treasureMap = Map[Int, String]() treasureMap += (1 -> "Go to island.") treasureMap += (2 -> "Find big X on ground.") treasureMap += (3 -> "Dig.")println(treasureMap(2))输出:Find big X on ground.

如果我们尝试从文件按行读取内容,代码可以如清单 20 所示。

清单 20. 读取文件
[root@localhost:2 bin]# cat hello.scalaimport scala.io.Source if (args.length > 0) {  for (line <- Source.fromFile(args(0)).getLines)  println(line.length + " " + line) } else Console.err.println("Please enter filename")运行命令: [root@localhost:2 bin]# ./scala hello.scala hello.scala输出结果:23 import scala.io.Source 23 if (args.length > 0) { 52 for (line <- Source.fromFile(args(0)).getLines) 42 println(line.length + " " + line) 7 } else 48 Console.err.println("Please enter filename")

清单 20 所示脚本从 scala.io 引入类 Source,然后检查是否命令行里定义了至少一个参数。表达式 Source.fromFile(args(0)),尝试打开指定的文件并返回一个 Source 对象。函数返回 Iterator[String],在每个枚举里提供一行包含行结束符的信息。

Scala 隐式引用了包 java.lang、scala 的成员、Predef 的单例对象。Predef 包括 println 和 assert 等等。清单 21 和 23 所示代码里,无论 ChecksumAccumulator.scala 还是 Summer.scala 都不是脚本,因为他们是以定义结束的。反过来说,脚本必然以一个结果表达式结束。因此如果您尝试以脚本方式执行 Summer.scala,Scala 解释器将会报错说 Summer.scala 不是以结果表达式结束的(当然前提是您没有在 Summer 对象定义之后加上任何您自己的表达式)。正确的做法是,您需要用 Scala 编译器真正地编译这些文件,然后执行输出的类文件。其中一种方式是使用 scalac,Scala 的基本编译器。输入$ scalac ChecksumAccumulator.scala Summer.scala 命令会编译您的源代码,每次编译器启动时,都要花一些时间扫描 jar 文件内容,并在即使您提交的是新的源文件也需要查看之前完成其他初始化工作。

因此,Scala 的发布包里还包括了一个叫做 fsc(快速 Scala 编译器)的 Scala 编译器后台服务:daemon。您可以这样使用: $ fsc ChecksumAccumulator.scala Summer.scala 第一次执行 fsc 时,会创建一个绑定在您计算机端口上的本地服务器后台进程。然后它就会把文件列表通过端口发送给后台进程去编译,后台进程完成编译。下一次您执行 fsc 时,后台进程就已经在运行了,于是 fsc 将只是把文件列表发给后台进程,它会立刻开始编译文件。使用 fsc,您只需要在第一次等待 Java 运行时环境的启动。如果想停止 fsc 后台进程,可以执行 fsc -shutdown 来关闭。

 

不论执行 scalac 还是 fsc 命令,都将创建 Java 类文件,然后您可以用 Scala 命令,就像之前的例子里调用解释器那样运行它。不过,不是像前面每个例子里那样把包含了 Scala 代码的带有.scala 扩展名的文件交给它解释执行,而是采用这样的方式,$ scala Summer of love。

本文对 Scala 语言的基础做了一些解释,由于篇幅所限,所以下一篇文章里会针对 Spark 附带的示例代码、Spark 源代码中出现的 Scala 代码进行解释。


 

文章参考http://www.ibm.com/developerworks/cn/opensource/os-cn-spark-scala/index.html
0 0
原创粉丝点击