在scala user郵件列表中看到一個函數,判斷一個對象是否是元組。從這個函數中,Easwy才了解到原來模式匹配(Pattern Match)也可以應用于正則表達式,這使得在scala中使用正則表達式(regex)更加容易了。另外,這個函數還展現了scala的另外兩個特點:
函數主體如下,為了方便講解,在前面加了行號:
val Ptrn = """scala.Tuple(d+)""".r def checka( x: Class[ _ ]) : Option[ Int ] = x.getName match { case Ptrn( i ) => Some( i.toInt ) case _ => { val sc = x.getSuperclass; if( sc != null ) checka( sc ) else None } } def isTuple( x: AnyRef ) = if( x.isInstanceOf[ Product ]) checka( x.getClass ) else None
行3定義了一個遞歸函數checka(),它的參數是Class[_],返回值是Option[Int]類型。參數”Class[_]“的意思是這個函數可以接受任意Class[A]類型,也就是接受任何參數化的Class類型(Type Parameterization)。
Easwy感覺checka()函數中的遞歸寫的不是很好,在看過”The Little Schemer”后,Easwy更傾向與下面的寫法:
def checka(x: Class[_]): Option[Int] = x match { case null => None case _ => x.getName match { case Ptrn(i) => Some(i.toInt) case _ => checka(x.getSuperclass) } }
下面是Easwy用來測試該函數的程序,全文如下:
object TestTuple { def main(args: Array[String]) { class ttt(a: Any, b: Any, c: Any) extends Tuple3(a, b, c) val test = List(new Tuple2(1, 2), new ttt(1, 2, 3), "Hello World") for (elem <- test) isTuple(elem) match { case None => println("Not Tuple") case Some(x) => println("Is Tuple" + x) } } val Ptrn = """scala.Tuple(d+)""".r def checka(x: Class[_]): Option[Int] = x match { case null => None case _ => x.getName match { case Ptrn(i) => Some(i.toInt) case _ => checka(x.getSuperclass) } } def isTuple( x: AnyRef ) = if( x.isInstanceOf[ Product ]) checka( x.getClass ) else None}
有興趣的朋友可以編譯運行一下,體會一下scala的簡捷與優雅。