首页 > 代码库 > Scala初探(二)

Scala初探(二)

5. 单例模式

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>class Marker(val color: String){
	//类中的任何代码段作为构造函数的一部分
	println("Creating " + this)

	override def toString(): String = "marker color " + color 
}

object MarkerFactory{
	private val markers = Map(
		"red" -> new Marker("red"),
		"blue" -> new Marker("blue"),
		"green" -> new Marker("green")
		)

	def getMarker(color:String) = if(markers.contains(color)) markers(color) else null	
}

println(MarkerFactory getMarker "blue")
println(MarkerFactory.getMarker("blue"))</strong></span>

Scala中创建单例对象特别简单,直接使用object关键字,而非class,因为单实例对象无法初始化,所以不能给它的主构造函数传递参数。Marker类表示对应于原色的彩笔,MarkFactory是一个单例,它预先创建了对应三原色的Marker的实例,这样就可以重用这些实例。

6. 独立对象和伴生对象

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>//marker的构造函数标记为private,但是伴生对象依然可以访问它
//在marker类或伴生对象之外创建marker实例,就会得到错误信息
class Marker private(val color: String){
	println("Creating " + color)

	override def toString(): String = "marker color " + color
}
//伴生对象
object Marker{
	private val markers = Map(
		"red" -> new Marker("red"),
		"blue" -> new Marker("blue"),
		"green" -> new Marker("green")
		)

	def getMarker(color: String) = if(markers.contains(color)) markers(color) else null
}

println(Marker getMarker "red")
println(Marker getMarker "bule")
println(Marker getMarker "blue")</strong></span>

单例对象MarkerFactory并未关联到任何一个类上。而Scala可以创建一个关联到类上的单例,使用同样的名字,它称为伴生对象;类和伴生对象之间没有界限,它们可以互相访问彼此的private字段和private方法。(Scala中类默认为public)

7. 容器

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>//容器
import java.util._

var list1: List[Int] = new ArrayList[Int]

list1 add 1
list1 add 2

var total = 0
for(i <- 0 until list1.size()){
	total += list1.get(i)
}


println("The total is " + total)</strong></span>

8. 高阶函数

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>def totalResultOverRange(number: Int,codeBlock: Int => Int): Int = {
	var result = 0
	for(i <- 1 to number){
		result += codeBlock(i)
	}

	result
}

println(totalResultOverRange(11,i => i))
println(totalResultOverRange(11,i => if(i%2 == 0) 1 else 0))</strong></span>

函数可以作为参数传递给函数,可以从函数中返回,甚至可以在函数中嵌套,这些就是高阶函数。上面例子中的函数参数codeBlock就是一个函数,Int=>Int 表示codeBlock这个函数的参数和返回类型是整型。

9.  具有多参数的高阶函数

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>def inject(arr: Array[Int],initial:Int,operation: (Int,Int) => Int): Int = {
	var carryover = initial
	arr.foreach(element => carryover = operation(carryover,element))

	carryover
}

val array = Array(2,3,5,1,6,4)
val sum = inject(array,0,(carryOver,elem) => carryOver + elem)

println("Sum of elements in array is " + sum)

val max = inject(array,0,(carryOver,elem) => Math.max(carryOver,elem))
println("Max of the array is " + max)</strong></span>

10. foldLeft()

<span style="font-family:KaiTi_GB2312;font-size:18px;"><strong>val array = Array(2,3,5,1,6,4)

val sum = (0 /: array){
	(sum,elem) => sum + elem
}

val max = (Integer.MIN_VALUE /: array){
	(large,elem) => Math.max(large,elem)
}

println("Sum of elements in array is " + sum)
println("Max of elements in array is " + max)</strong></span>

(0 /: array)就相当于foldLeft(),这个方法表示array中每个元素累加,将sum初始化为0,每次累加后将结果返回给sum。


Scala初探(二)