开始Scala最简单的的方式就是Scala解释器,一个用于编写Scala表达式和程序的交互式“shell”
1 Scala解释器的使用
1 result0
- 其中res0意思是result0,是自动生成的变量名,指向被计算出来的值
2 多行录入
- 要在解释器中多行录入代码,只需要在第一行之后直接按回车继续就好,
如果当前键入的内容不完整,解释器会自动在下一行的头部加上竖线(|)
3 错误退出
- 如果你意识到输错了,但解释器还在等待你的输入,可以通过连续敲两次回车来退出
4 退出解释器
:q或者:quit
2 编写Scala脚本
脚本不过是一组依次执行的语句
1 入门脚本编写
println("Hello, " + args(0) + "!")
- 命令行参数可以通过名为args的Scala数组获取,Scala数组下标从0开始,可以通过圆括号指定下标来访问对应下标的元素
- 将上面代码放入名为hello.scala文件中,然后执行
scala hello.scala earth
,在这个命令中,字符串"earth"被当做命令行参数传入,然后在脚本中用args(0)访问,因此你会看到这样的结果:Hello, earth!
2 浅谈数组
val greetStrings = new Array[String](2)
greetStrings(0) = "Hello"
greetStrings(1) = " World"
for (i <- 0 to 1)
print(greetString(i)
- Scala的数组的访问方式是将下标放在圆括号中
- 当你用val定义一个变量时,变量本身不能被重新赋值,但它指向的那个对象是有可能发生改变的
- 数组本身是可变的
- for表达式这一行展示了Scala的一个通行规则:如果一个方法只接收一个参数,在调用它的时候,可以不使用英文句点或圆括号,本例中的to实际上是接收了一个Int参数的方法,代码
0 to 1
会被转换为(0). to(2)
,这种方式仅在显式地给出方法调用的目标对象时才有效,不能写println 10
,但是可以写Console println 10
- 当你用一组圆括号将一个或多个值包起来,并将其应用(apply)到某个对象时,Scala会将这段代码转换成对这个对象的一个名为apply的方法的调用,所以greetString(i)会被转换成greetString.apply(i),在Scala中访问一个数组的元素就是一个简单的方法调用,当然,这样的代码仅在对象的类型实际上定义了apply方法时才能编译通过
- 同理,当我们尝试对通过圆括号应用了一个或多个参数的变量进行赋值时,编译器会将代码转换成update方法的调用,这个update方法接收两个参数,例如
greetStrings(0) = "Hello"
会被转换成:
greetStrings.update(0,"Hello")
这两种写法在语义上相同
- 但是Scala还提供了一更简洁的方式来创建和初始化数组
val numStrings = Array("zero", "one", "two")
- 上面的方式实际上是调用了一个名为apply的工厂方法,这个方法创建并返回了新的数组,这个apply方法接收一个变长的参数列表,类似于如下写法
val numStrings = Array.apply("zero","one","two")
3 浅谈列表
- Scala的List和Java的List不同在于,Scala的List是不可变的,而java的是可变的
- 当你调用列表的某个方法,而这个方法的名字看上去像是会改变列表的时候,它实际上是返回一个新列表,例如,List有个方法叫
:::
,用于列表拼接
val oneTwo = List(1,2,3)
val threeFour = List(3,4)
val oneTwoThreeFour = oneTwo ::: threeFour
// oneTwoThreeFour 结果为List(1,2,3,4)
- 也许列表上用的最多的操作是
::
,读作cons
,表示在一个已有列表的最前面添加一个新的元素,并返回这个新的列表,例如
val twoThree= List(2,3)
val oneTwoThree = 1 :: twoThree
// oneTwoThree 结果为List(1,2,3)
- 在表达式
1 :: twoThree
中,::
是它右操作元的方法,如果一个方法被用在操作符表示法当中时,比如a * b
,方法默认调用都发生在左操作元,但是方法名若以为冒号:
结尾,该方法的调用会发生在它的右操作元上,因此该表达式等同于twoThree.::(1)
- 表示空列表的快捷方式是Nil,List()也能表示空列表,也可以用如下方式创建列表
val oneTwo = 1 :: 2 :: Nil
// one结果为List(1,2)
- 之所以要在末尾放一个Nil,是因为
::
是List类上定义的方法,如果只是写成1::2
,编译不通过,因为3是Int,没有::
方法 - 为什么不在列表末尾追加元素?
List类的确提供了追加(append)操作,写作 :+ 但是这个操作很少被使用,因为往列表末尾
追加元素的操作所需要的时间随着列表的大小线性增长,而使用 :: 在列表的前面添加元素
只需要固定的时间,如果想通过追加元素的方式高效地构建列表,可以依次在头部添加完
成后,再调用reverse,也可以用ListBuffer,这是个可变的列表,它支持追加操作,完成
后调用toList即可
4 Tips
- Java的
++i
和i++
在Scala中并不工作,要想变量在Scala中自增,要么用i = i + 1
或者i += 1
- 在Scala中,while或if语句中的boolean表达式必须放在圆括号里,如
if (i < 0)
,如果if代码块只有单一申明,可以选择不写花括号,如
if (i !=0 )
print(" ")
- 关于for表达式,如下代码中,<- 的左边是arg,这是一个val变量的名字,注意它不是var,又因为它总是val,只能写成
arg
,而不能写成val arg
for (arg <- args)
println(arg)