使用类型参数化数组(Array)
在scala中使用new实例化对象(或者叫类实例)。实例化过程中,可以用值和类型使对象参数化。参数化的意思是指在创建实例的同时完成对它的“设置”。
例如,
val greeting:Array[String] = new Array[String](3)
greeting(0) = “Hello”
greeting(1) = “ ”
greeting(2) = “World”
greeting.foreach((word:String) => print(word))
其中,类型参数是[String],值参数是(3),因此其初始长度为3.
注意,当同时用类型和值参数化实例的时候,应该先写方括号和类型参数,然后再写圆括号和值参数。
数组是scala中的一种类。用括号传递给变量一个或多个值时,scala会调用apply方法。
greeting(0) 等价 greeting.apply(0)
与之类似的还有update方法。
greeting(0) = “Hello”等价greeting.update (0,“Hello”)
使用列表list
Array[String](3)虽然长度和类型不可变,但是其元素可变。而list一旦创建就不可变。
列表最常见的操作符是“::”。它可以把新元素添加到现有列表的最前端,然后返回作为执行结果的新列表。
val twoThree:List[Int] = List(2,3)
val oneTwoThree =1::twoThree
println(oneTwoThree)
而使用操作符“:::”,可以将两个列表拼接在一起组成一个新的list。
Tips:
注意到,valoneTwoThree = 1::twoThree,“::”是右操作数的方法。凡是以“:”为结尾的方法都是被右操作数调用。上式可以写成,twoThree.::(1)。通常情况下,方法都是被左操作数调用。例如a+b,可以写成a.+(b)。
为什么列表不支持添加(append)操作?
List类没有提供类似python中append操作,因为随之列表的变长,append的耗时将呈线性增长,而使用::做前缀仅消耗固定的时间。
使用元祖(Tuple)
与列表一样,元祖也是不可变的;但与列表不同,元祖可以包含不同类型的元素。
元祖实例化后可以用点号、下划线和基于1的索引访问其中的元素。
元祖的实际类型取决于它含有的元素数量和这些元素的类型。
val pair: Tuple2(Int,String)= Tuple2(1,”Scala”)
println(pair._1)
println(pair._2)
Tips
访问元祖的元素
为什么元祖不能像列表一样用Tuple.(i)来访问元素?那是因为列表的apply方法始终返回同一类型的元素,但元祖中的元素的类型不尽相同。另外元祖的元素访问是基于1的不是基于0。这是因为对于静态类型的元祖的其他语言,从1开始是传统的设定。
编写脚本和读取文件
Scala脚本的命令行参数保存在args的scala数组中。
下例中,表达式Source.Source.fromFile(args(0))尝试打开指定文件并返回Source对象。之后调用getLines返回Iterator[String]。迭代器每次返回一行文本,包括行结束符。
脚本名test.scala
命令:scala test.scala test.scala
importscala.io.Source
defwidthOfLength(s: String) = s.length.toString.length
if(args.length>0){
val lines =Source.fromFile(args(0)).getLines.toList
val longestLine = lines.reduceLeft{
(a,b)=>if(a.length>b.length) a elseb
}
val maxWidth = widthOfLength(longestLine)
for(line<-lines){
val numSpaces = maxWidth -widthOfLength(line)
val padding = ""*numSpaces
println(padding+line.length+"|"+line)
}
}
else{
Console.err.println("Please inputfile'names")
}