Why Scala
- JVM 生态
- 简洁
- 类型推断
- 函数式
- 多范式
- Actor
下面的所有操作都在 Scala REPL 中进行
表达式
1 2
| scala> 1 + 1 res0: Int = 2
|
res0 是解释器自动创建的变量名称,用来指代表达式的计算结果。它是 Int 类型,值为 2。意味着你可以继续使用这个变量。
1 2
| scala> res0 + 1 res1: Int = 3
|
Scala 中(几乎)一切都是表达式。
值 (val) 和变量 (var)
你可以给一个表达式的结果起个名字赋成一个不变量(val)。
1 2 3 4 5
| scala> val two = 1 + 1 two: Int = 2 scala> two = 3 ^ error: reassignment to val
|
你不能改变这个不变量的值,但如果是 var 声明的就可以改变。
函数
你可以使用 def
创建函数。
1 2
| scala> def addOne(m: Int): Int = m + 1 addOne: (m: Int)Int
|
你可以创建匿名函数。
1 2
| scala> (x: Int) => x + 1 res2: (Int) => Int = <function1>
|
你可以把匿名函数赋值给 val。
1 2 3 4 5
| scala> val addOne = (x: Int) => x + 1 addOne: (Int) => Int = <function1>
scala> addOne(1) res4: Int = 2
|
你可以部分应用一个函数
1 2 3 4 5 6 7 8 9
| scala> def adder(m: Int, n: Int) = m + n adder: (m: Int,n: Int)Int
scala> val add2 = adder(2, _:Int) add2: (Int) => Int = <function1>
scala> add2(3) res50: Int = 5
|
你可以柯里化函数 (Currying Function)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| scala> def multiply(m: Int)(n: Int): Int = m * n multiply: (m: Int)(n: Int)Int
scala> multiply(2)(3) res0: Int = 6
scala> val timesTwo = multiply(2) _ timesTwo: (Int) => Int = <function1>
scala> timesTwo(3) res1: Int = 6
scala> (adder _).curried res1: (Int) => (Int) => Int = <function1>
|
你可以参数可变参数函数
1 2 3 4 5 6 7 8
| def capitalizeAll(args: String*) = { args.map { arg => arg.capitalize } }
scala> capitalizeAll("rarity", "applejack") res2: Seq[String] = ArrayBuffer(Rarity, Applejack)
|
OOP
类、继承和 Java 比较类似。额外的 Scala 还引入了
- trait。实现类似于 Ruby、Python 这样的动态语言的 mix-in
- object 关键字 和 apply() 方法。方便实现 single instance
- case class。为方便存放值和模式匹配引入了
Trait
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| trait Car { val brand: String }
trait Shiny { val shineRefraction: Int } class BMW extends Car { val brand = "BMW" }
class BMW extends Car with Shiny { val brand = "BMW" val shineRefraction = 12 }
|
object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| object Timer { var count = 0
def currentCount(): Long = { count += 1 count } }
scala> Timer.currentCount() res0: Long = 1
class Bar(foo: String) object Bar { def apply(foo: String) = new Bar(foo) }
|
case class
1 2 3 4 5 6 7 8
| case class Calculator(brand: String, model: String) def calcType(calc: Calculator) = calc match { case Calculator("HP", "20B") => "financial" case Calculator("HP", "48G") => "scientific" case Calculator("HP", "30B") => "business" case Calculator(_, _) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel) case _ => "Not a calculator" }
|