变量
类型
所有的Java原始类型在scala包里都有对应的类。
eg:
scala.Boolean对应着Java的boolean。
scala.Float对应着Java的float。
当你把你的Scala代码编译成Java字节码,Scala编译器将使用Java的原始类型以便获得其带来的性能益处。
Java中变量的类型指定在其名称之前,与之不同的是,Scala里变量的类型在其名称之后,用冒号分隔
val和var
val类似于Java里的final变量。一旦初始化了,val就不能再赋值了。
eg:
val msg = "Hello, world!"
val msg : String = "Hello, world!"
var如同Java里面的非final变量。var可以在它生命周期中被多次赋值
eg:
var greeting = "Hello, world!"
var greeting : String = "Hello, world!"
Scala变量特性:
类型推断:type inference,能自动理解你省略的类型的能力
val msg = "Hello, world!"
函数
def 函数名 ([变量名:类型[,变量名:类型]]) [: 结果类型] = { 逻辑语句 }
函数的定义用def开始。函数名,括号里带有冒号分隔的参数列表。
结果类型:如果函数是递归的,必须显式地定义函数结果类型
eg:
def max(x: Int, y: Int): Int = {
if (x > y) x else y
}
既不带参数也不返回有用结果的函数定义
eg:
def greet() = println("Hello, world!")
当你定义了greet()函数,解释器会回应一个greet: ()Unit。
“greet”当然是函数名。
空白的括号说明函数不带参数。
Unit是greet的结果类型。Unit类型比较接近Java的void类型,而且实际上Java里每一个返回void的方法都被映射为Scala里返回Unit的方法
PS:
每个函数参数后面必须带前缀冒号的类型标注,因为Scala编译器没办法推断函数参数类型
scala用 if (x > y) x else y 代替了 java中的三目运算(“(x > y) ? x : y)
脚本
hello.scala文件中: println("Hello, world, from a script!”)
在命令行中执行:scala hello.scala
名为args的数组可以获得传递给Scala脚本的命令行参数 Scala里,数组以零开始,通过在括号里指定索引访问一个元素 args(0)
hello.scala文件中: println("hello,"+args(0))
在命令行中执行:scala hello.scala vitohuang
逻辑语句
while、foreach 和 for
eg:脚本:
while :
var i = 0
while (i < args.length) {
println(args(i))
i += 1
}
PS:Scala里自增,必须写成 i = i + 1 或者 i += 1
foreach :
args.foreach(arg => println(arg)) 【Scala特别简洁的优越性】
<=>
args.foreach((arg: String) => println(arg))
PS:这种方式需要把参数部分包裹在括号里
<=>
args.foreach(println)
PS:若函数只有一个参数时,则可以用此方式
for :
for (arg <- args) println(arg)
PS:arg 并不是var而是val,arg不能在for表达式的函数体中重新赋值
每个args数组的元素都被val被创建并赋值,然后for的函数体将被执行
集合
Set
Scala致力于帮助你充分利用函数式和指令式风格两方面的好处,它的集合类型库于是就区分了集合类的可变和不可变。例如,数组始终是可变的,而列表始终不可变。
集和映射,Scala同样提供了可变和不可变的替代品
var city = Set("beijing", "shanghai")
Scala中创建集的方法与创建列表和数组的类似:通过调用Set伴生对象的名为apply的工厂方法
city += "chongqing"
要向集加入新的变量,可以在集上调用+,传入新的元素。可变的和不可变的集都提供了+方法,但它们的行为不同。可变集将把元素加入自身,不可变集将创建并返回一个包含了添加元素的新集。通过可变和不可变的Set工厂方法制造的缺省的集实现很可能能够满足极大多数的情况,但偶尔你也或许想要个显式的集
需要不可变集,就需要使用一个引用:import,语法是相同的。只要引用你需要的类,并使用它伴生对象的工厂方法即可
eg:
可变:scala.collection.mutable.Set
不可变:scala.collection.immutable.Set
可变与不可变声明时的区别:
代码1:
var jetSet = Set("Boeing", "Airbus")
jetSet += "Lear" println(jetSet.contains("Cessna"))
代码2:
import scala.collection.mutable.Set
val movieSet = Set("Hitch", "Poltergeist")
movieSet += "Shrek" println(movieSet)
集是可变的,所以代码2不需要对movieSet重新赋值,所以它是val相对的,在代码2中对可变集使用+=需要对jetSet重新赋值,因此它是var
PS:若不用import声明,scala自动创建成不可变的!
Map
Scala采用了类继承机制提供了可变的和不可变的两种版本的Map,Map的类继承机制看上去和Set的很像。
scala.collection包里面有一个基础Map特质和两个子特质Map:可变的Map在scala.collection.mutable里,不可变的在scala.collection.immutable里。
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))
显式类型初始化“[Int, String]”,对于可变的集合且映射为空【Map[Int, String]() 】,没有任何值被传递给工厂方法,编译器无法推断映射的类型参数,因此可变的集合且映射为空必须进行显示类型初始化。