Scala学习笔记
命令行中输入 scala ,则进入 scala 解释器
变量
Scala 定义了两种类型的变量 val 和 var。
- val类似于 Java 中的final 变量,一旦初始化之后,不可以重新复制(我们可以称它为常变量)。
-
var类似于一般的非final 变量。可以任意重新赋值。
在定义这个变量时并不需要像 Java 一样定义其类型,Scala 可以根据赋值的内容推算出变量的类型。这在 Scala 语言中成为 “type inference”。当然如果你愿意,你也可以采用和 Java 一样的方法,明确指定变量的类型。
scala> val msg = "Hello again,world"
scala> val msg2:String = "Hello again,world"
在Scala中,修正==和!=运算符的含义。在Scala中,==和!=是执行对象的值比较,相当于Java中的equals方法(实际上编译器在编译时也是这么做的)。而对象比较需要使用eq和ne两个方法来实现。
函数
Scala 函数以 def 定义,然后是函数的名称(如 max),然后是以逗号分隔的参数。Scala 中变量类型是放在参数和变量的后面,以“:”隔开。这种做的一个好处是便与 “type inference”。如果函数需要返回值,它的类型也是定义在参数的后面(实际上每个 Scala 函数都有返回值,只是有些返回值类型为 Unit,类似为 void 类型)。
scala> def max(x:Int,y:Int):Int ={
| if (x >y) x
| else y
| }
max: (x: Int, y: Int)Int
scala> def greet() = println("hello,world")
greet: ()Unit
此外每个 Scala 表达式都有返回结果(这一点和 Java,C# 等语言不同),比如 Scala 的 if else 语句也是有返回值的,因此函数返回结果无需使用 return 语句。Scala 代码不使用 return 语句,函数的最后一行的值就可以作为函数的返回值。
if 表达式
var filename="default.txt"
if(!args.isEmpty)
filename =args(0)
或
val filename=
if(!args.isEmpty) args(0) else "default.txt"
使用 foreach和 for 来实现迭代
args.foreach(arg => println(arg))或
args.foreach(println)或
for (arg <-args)
println(arg)
Array数组
val greetStrings =new Array[String](3)
greetStrings(0)="Hello"
greetStrings(1)=","
greetStrings(2)="world!\n"
for(i <- 0 to 2)
print(greetStrings(i))
- Array对象可修改
- 使用[]来为数组指明类型化参数
- 访问数组使用()而非[]。
List
val oneTwo = List(1,2)
val threeFour = List(3,4)
val oneTwoThreeFour = oneTwo ::: threeFour
//:::操作符(其实为:::方法)将两个列表链接起来
scala> val oneTowThree = 1 :: 2 ::3 :: Nil
oneTowThree: List[Int] = List(1, 2, 3)
- List对象是不可修改的
- List 只能包含同类型的数据
Tuples
val pair=(99,"Luftballons")
println(pair._1)
println(pair._2)
- 一旦定义了一个元组,可以使用 ._来访问员组的元素(矢量的分量,注意和数组不同的是,元组的索引从 1 开始)。
- Tuples 可以包含不同类型的数据
- 元祖的实际类型取决于它的分量的类型,比如上面 pair 的类型实际为 Tuple2[Int,String],而 (‘u’,’r’,”the”,1,4,”me”) 的类型w为Tuple6[Char,Char,String,Int,Int,String]。
Set与Map
var jetSet = Set ("Boeing","Airbus")
jetSet +="Lear"
println(jetSet.contains("Cessna"))
scala> val romanNumeral = Map ( 1 -> "I" , 2 -> "II", 3 -> "III", 4 -> "IV", 5 -> "V")
romanNumeral: scala.collection.immutable.Map[Int,String] = Map(5 -> V, 1 -> I, 2 -> II, 3 -> III, 4 -> IV)
scala> romanNumeral(1)
res8: String = I
for 表达式
- 过滤
某些时候,你不想枚举集合中的每个元素,而是只迭代某些符合条件的元素,在 Scala 中,你可以为 for 表达式添加一个过滤器–在 for 的括号内添加一个 if 语句
val filesHere = (new java.io.File(".")).listFiles
for( file <-filesHere
if file.isFile
if file.getName.endsWith(".scala")
) println(file)
其中如 file < – filesHere 的语法结构,在 Scala 中称为“生成器 (generator)”。 本例中 filesHere 的类型为 Array[File],每次迭代 变量 file 会初始化为该数组中一个元素, File 的 toString()为文件的文件名,因此 println(file)打印出文件名。 Scala 的 for 表达式支持所有类型的集合类型,而不仅仅是数组。
- 嵌套迭代
val filesHere = (new java.io.File(".")).listFiles
def fileLines (file : java.io.File) =
scala.io.Source.fromFile(file).getLines().toList
def grep (pattern: String) =
for (
file if file.getName.endsWith(".scala");
line <-fileLines(file)
if line.trim.matches(pattern)
) println(file + ":" + line.trim)
grep (".*gcd.*")
或
val filesHere = (new java.io.File(".")).listFiles
def fileLines (file : java.io.File) =
scala.io.Source.fromFile(file).getLines().toList
def grep (pattern: String) =
for {
file if file.getName.endsWith(".scala")
line <-fileLines(file)
if line.trim.matches(pattern)
} println(file + ":" + line.trim)
grep (".*gcd.*")
注意第一个代码中两个迭代之间使用了”;”,如果你使用{} 替代 for 的()的括号,你可以不使用“;”分隔这两个“生成器”,这是因为 Scala 编译器不推算包含在括号内的省掉的“;”。
- 生成新集合
scala> val a = for {
| x <- 1 to 10
| }yield x
a: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Match表达式
Scala 的 Match 表达式支持从多个选择中选取其一,类似其它语言中的 switch 语句。通常来说,Scala 的 match 表达式支持任意的匹配模式。
val firstArg = if (args.length >0 ) args(0) else ""
firstArg match {
case "salt" => println("pepper")
case "chips" => println("salsa")
case "eggs" => println("bacon")
case _ => println("huh?")
}
这段代码和 Java 的 switch 相比有几点不同:
一是任何类型的常量都可以用在 case 语句中,而不仅仅是 int 或是枚举类型。
二是每个 case 语句无需使用 break,Scala不支持“fall through”。
三是 Scala 的缺省匹配为”_”,其作用类似 java 中的 default。
而最关键的一点是 scala 的 match 表达式有返回值,上面的代码使用的是 println 打印,而实际上你可以使用表达式,比如修改上面的代码如下:
val firstArg = if (args.length >0 ) args(0) else ""
val friend = firstArg match {
case "salt" => "pepper"
case "chips" => "salsa"
case "eggs" => "bacon"
case _ => "huh?"
}