第一个Scala程序
从Hello World开始
object Hello extends App {
println("Hello, world")
}
Scala REPL
REPL( read - evaluate - print - loop ) 命令行解释器。理解起来就是我们浏览器开发工具中的console.
它能根据我们的输入进行计算,然后将计算结果输出到终端,并等待用户的下一步输入
可以借助scala repl工具,快速验证我们的代码逻辑,我比较喜欢这种即时反馈的方式。
scala> val x = 1
x: Int = 1
scala> val y = x + 1
y: Int = 2
变量声明(val 和 var)
val
使用val声明的变量为不可变变量, 等同于Java中使用final修饰的变量(比较推荐使用,-- 函数式编程中,不可变原则)
var
使用var声明的变量为可被修改的变量,在scala中,一般更加推荐使用val来修饰变量,除非有特殊原因,才选择var。
var
creates a mutable variable, and should only be used when there is a specific reason to use it
val x = 1 //immutable
var y = 0 //mutable
定义变量类型
在scala中,创建变量时并不需要指定他们的类型。Scala能够帮我们处理类型映射。
此功能称为类型推断,它是确保代码简洁的好方法。
比如:
val x = 1
val s = "a string"
val p = new Person("Regina")
也可以显式声明变量的类型,但是,写多Scala代码之后,会觉得并无必要显式声明变量的类型:
val x: Int = 1
val s: String = "a string"
val p: Person = new Person("Regina")
流程控制
if / else
Scala的 if/else 和其他语言相似
if (test1) {
doA()
} else if (test2) {
doB()
} else if (test3) {
doC();
} else {
doD();
}
但是,与其他语言有所区别的是,if/else 会返回值,所以,我们可以像下面这样写:
val x = if (a < b) a else b
在Scala中,不支持三目运算符哦.
match expressions
就像是switch . case 的用法,同样,它也是可以返回值的情况.
val result = i match {
case 1 => "one"
case 2 => "two"
case _ => "not 1 or 2"
}
代码中,用于匹配的数据类型,可以为任意的数据类型.
val booleanAsString = bool match {
case true => "true"
case false => "false"
}
以下是另一个处理不同类型匹配的方法代码:
def getClassAsStrin (x: Any): String = x match {
case s: String => s + " is a String"
case i: Int=> "Int"
case f: Float=> " Float"
case l: Listp[_]=> "List"
case s: Person=> "Person"
case _ => "Unknown"
}
强大的匹配表达式,也是Scala的一大特性。
try/catch
用于异常捕获。功能与Java相似,不同的是其语法。
try {
writeToFile(text)
} catch {
case fnfe: FileNotFoundException => println(fnfe)
case ioe: IOException => println(ioe)
}
for循环
要掌握一个符号 <-
,这个符号的右边是一个数据集合,符号的左边是当前循环变量。
for (arg <- args) println(arg)
// "x to y" syntax
for (i <- 0 to 5) println(i)
// "x to y by" syntax
for (i <- 0 to 10 by 2) println(i)
yield
可以令每一次循环的结果都记录返回。比如:
val x = for (i <- 1 to 5) yield i * 2
另一个例子:
val fruits = List("apple", "banana", "lime", "orange")
val fruitsLengths = for {
f <- fruits
if f.length > 4
} yield f.length
while 和 do..while
// ( while loop )
while(condition) {
statement(a)
statement(b)
}
// ( do-while )
do {
statement(a)
statement(b)
} while(condition)
类
定义一个类
class Person(var firstName: String, var lastName: String) {
def printFullName () = println(s"$firstName $lastName")
}
类的使用
val p = new Person("J", "Paul")
println(p.firstName)
println(p.lastName)
p.printFullName()
方法
方法声明
Scala的类也同样可以拥有方法,定义scala方法的方式如下:
def sum(a: Int, b: Int) = a + b
def concatenate(s1: String, s2: String) = s1 + s2
方法调用
val x = sum(1, 2)
val y = concatenate("foo", "bar")
scala的方法参数还支持提供默认值哦.
Traits
trait 用于特征,它包含的是一组方法,这组方法的功能围绕其定义的特征。让您将代码分解为小型模块化单元。
下面我们定义两种行为特征:
trait Speaker {
def speak(): String // has no body, so it’s abstract
}
trait Runner {
def startRunning(): Unit = println("I'm running")
def stopRunning(): Unit = println("Stopped running")
}
class Dog(name: String) extends Speaker with Runner {
def speak(): String = "Woof!"
}
如果 trait 中包含抽象方法,则继承该 trait 的非抽象类需要提供该方法的方法实现。
集合类
如果您是从Java来的Scala,并且已经准备好真正地学习Scala,则可以在Scala中使用Java集合类,有些人会花几个星期或几个月的时间来熟悉Scala。
但是强烈建议您学习基本的Scala集合类
— List
, ListBuffer
, Vector
, ArrayBuffer
, Map
, and Set
—
Scala集合类的一大优点是,它们提供了许多强大的方法,让我们编写出更加简化的代码。
List - 添加元素
可以有多种添加元素的方式,比如:
val nums = List.range(0, 10)
val nums = (1 to 10 by 2).toList
val letters = ('a' to 'f').toList
val letters = ('a' to 'f' by 2).toList
集合 - 操作
集合遍历的方式有多种,这些遍历方式适用的集合类型有 Array
, ArrayBuffer
, Vector
, List
,还有更多其他的..
数据准备:
val nums = (1 to 10).toList
val names = List("joel", "ed", "chris", "maurice")
遍历 - foreach
foreach 循环比遍历元素.
names.foreach(println)
// 输出结果:
/*
joel
ed
chris
maurice
*/
条件过滤 - filter
对集合元素过滤.得到新的集合.
使用filter,我们需要提供一个布尔表达式.
在集合中满足该表达式的元素将被筛选下来,这些被选中的元素数据,将作为集合形式由filter方法返回。
nums.filter(_ < 4).foreach(println)
/*
输出结果:
1
2
3
*/
元素映射 - map
集合的map函数,提供了一种根据当前元素衍生成另一种元素的方式。
使用map函数,我们需要提供处理(转换)元素的方法,。这个方法将作为map函数的参数,在map内部中会令每一个元素都根据我们提供的方法转换数据,最后转换结果数据以新集合的形式由map方法返回。
// 每个元素值乘以2后返回
scala> val doubles = nums.map(_ * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
// 每个元素处理成首字母大写情况后返回
scala> val capNames = names.map(_.capitalize)
capNames: List[String] = List(Joel, Ed, Chris, Maurice)
// 每个元素处理成布尔值后返回
scala> val lessThanFive = nums.map(_ < 5)
lessThanFive: List[Boolean] = List(true, true, true, true, false, false, false, false, false, false)
Scala 的集合类还提供了更多使用的方法,后面继续发掘。
可以从这些教程中获得更多Scala集合类的使用方法
the Scala Book collections lessons
the Mutable and Immutable collections overview
元组 - Tuples
元组,也是存放元素的集合类型,它的语法如下:
val t = (11, "Eleven", new Person("Eleven"))
我们可以通过元素在元组中的序号来访问,也可以为元组中元素分配到具名的变量中。
val (num, string, person) = (11, "Eleven", new Person("Eleven"))