REPL
Scala REPL (“Read-Evaluate-Print-Loop”) 是命令行解释器,在这你可以测试你的Scala代码。
只需在你的操作系统命令行里输入 scala ,就可以启动一个 REPL 会话。就像下面:
$ scala
Welcome to Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> _
因为 REPL 是一个命令行解释器,它就待在那里等待你的输入。你可以在 REPL 中输入一些Scala 表达式,看看它是如何运行的:
scala> val x = 1
x: Int = 1
scala> val y = x + 1
y: Int = 2
正如你多看到的,在REPL里输入你的表达式,会在下一行看到运行的结果。
根据需要创建的变量
如果你没有把表达式的结果赋给一个变量,REPL 会自动的为其创建一个以 res 开头的变量。第一个变量是 res0 , 第二个变量是 res1 ,以此类推。
scala> 2 + 2
res0: Int = 4
scala> 3 / 3
res1: Int = 1
它们是动态地自动创建的实际变量名,你可以在表达式中使用它们:
scala> val z = res0 + res1
z: Int = 5
在本书中,你会经常使用到REPL。所以进一步的尝试使用它吧。下面有一些表达式,你可以尝试看看它们在REPL中会如何运行:
val name = "John Doe"
"hello".head
"hello".tail
"hello, world".take(5)
println("hi")
1 + 2 * 3
(1 + 2) * 3
if (2 > 1) println("greater") else println("lesser")
除了REPL,下面有几个其他的你可以使用的类似REPL的工具:
- Scastie 是 Scala的交互式环境 ,具有很多很好的特性,包括控制构建设置和分享代码段。
- IntelliJ IDEA 有一个 工作表插件 可以让你在IDE里做这类的事情。
- Scala IDE for Eclipse 也有一个这样的工作表插件
- scalafiddle.io 让你可以在网络浏览器里运行类似的表达式。
还有更多的信息,可以从 Scala REPL 获取。
两种变量的类型
在Java中,你会像下面这样声明新的变量:
String s = "hello";
int i = 42;
Person p = new Person("Joel Fleischman");
每个变量声明的前面是它的类型。
不同的是,Scala有两种类型的变量:
- val 创建一个不可变的变量(像Java中的final)
- var 创建一个可变的变量
下面是在Scala中变量声明的形式:
val s = "hello" // immutable
var i = 42 // mutable
val p = new Person("Joel Fleischman")
上面这些例子说明,Scala编译器通常是足够智能的,可以推断出 = 号右边代码的数据类型。我们说变量的类型被编译器推断出来。
如果你喜欢也可以明确的给定数据类型:
val s: String = "hello"
var i: Int = 42
在大多数情况下,编译器不需要看到这些明确的类型,但如果你想你的代码可读性好些也可以加上它们。
在实践中,当你使用第三方库中的方法时,尤其是你不经常使用的或是从方法名不能看出类型时,
标明类型也有助于明确地显明类型。
val 与 var 的不同
val 与 var 之间的不同是,val 产生一个不可变的变量,像Java中的final, var 产生一个可以改变的变量。
因为val字段不能改变,一些人把它作为值来引用,而不是变量。
下面是在REPL中,当你把一个val字段重新分配时所发生的:
scala> val a = 'a'
a: Char = a
scala> a = 'b'
<console>:12: error: reassignment to val
a = 'b'
^
如期望的那样,出现了“reassignment to val”的错误。
不同的是,你可以重新赋值一个 var字段:
scala> var a = 'a'
a: Char = a
scala> a = 'b'
a: Char = b
在Scala中,一般原则是,你应该总是使用val 字段,除非你要很好的理由拒绝这样。这个简单的规则会使你的代码更像代数,有助于你走进函数式编程的世界,在那里所有的字段都是不可变的。
带val字段的“Hello World”
下面是带有val 字段的“Hello World” 程序:
object Hello3 extends App {
val hello = "Hello, world"
println(hello)
}
像之前一样:
- 保存代码到Hello3.scala的文件中
- 用scalac 编译 Hello3.scala
- 使用 "scala Hello3 " 来运行
在REPL中带val字段的一个说明
REPL中的运行 与 IED中使用源代码来运行不是100%一样的。因此这样一些在REPL能做,但在真实的项目代码中不能如此。
一个例子是,在REPL你可以重新定义val字段:
scala> val age = 18
age: Int = 18
scala> val age = 19
age: Int = 19
在真实代码中val 是不能被重新定义的,但在REPL环境下可以。