64.scala编程思想笔记——使用元组的模式匹配
欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/50458742
源码下载连接请见第一篇笔记。
先看枚举如下:
package paintcolors
object Color extends Enumeration {
type Color =Value
val red,blue, yellow, purple,
green,orange, brown = Value
}
创建一个blend方法,展示将两种颜色混合起来时产生的颜色。
如下:
import paintcolors.Color
import paintcolors.Color._
package object colorblend {
def blend(a:Color, b:Color) =
(a, b) match{
case _ if a== b => a
case(`red`, `blue`) |
(`blue`, `red`) => purple
case(`red`, `yellow`) |
(`yellow`, `red`) => orange
case(`blue`, `yellow`) |
(`yellow`, `blue`) => green
case(`brown`, _) |
(_,`brown`) => brown
case _=> // Interesting, not accurate:
Color((a.id + b.id) % Color.maxId)
}
}
注意,在所有颜色名字上都添加了右单引号。这是case语句的一种特性,如果在=>左侧看到了非大写的名字,就会创建一个局部变量,用来计算该模式匹配。如果用右单引号将名字括起来,那么就是告诉scala将该名字当做符号处理。
测试代码如下:
import com.atomicscala.AtomicTest._
import paintcolors.Color._
import colorblend.blend
blend(red, yellow) is orange
blend(red, red) is red
blend(yellow,blue) is green
blend(purple,orange) is blue
blend(purple,brown) is brown
可以从输入的元组中产生一个输出的操作通常称为查表,可以将输入元组中的每个元素都看作表的一个维度。通过使用Map,可以以另一种方式来解决这个问题,即提前生成这张表,而不是每次都要计算结果,如下:
import com.atomicscala.AtomicTest._
import paintcolors.Color
import paintcolors.Color._
val blender = (
for {
a <-Color.values.toSeq
b <-Color.values.toSeq
c =colorblend.blend(a, b)
} yield ((a,b), c)
).toMap
blender.foreach(println)
def blend(a:Color,b:Color) = blender((a,b))
blend(red, yellow) is orange
blend(red, red) is red
blend(yellow,blue) is green
blend(purple,orange) is blue
blend(purple,brown) is brown