Scala : 2 days ago

2 days ago 可以是一行代码,如同java里(int i=0;)可以通过编译,太Cool了,如同一句日常用语,非常吸引人;这行代码是在《Programming Scala:multi...》7.5节"隐式类型转换"里看到的,书里ago好像用的是String类型的,缺乏美观,虽是本入门级的书,不过入门级却 不一定是写的很薄,可以做一些全面的介绍而不求讲的很深入;

于是自己就改编了一下:

import java.text.SimpleDateFormat  
    import java.util.{Calendar,Date}  
      
    sealed abstract class Day  
    abstract class Forward extends Day  
    abstract class Backward extends Day  
    case object ago extends Backward  
    case object before extends Backward  
    case object after extends Forward  
    case object later extends Forward  
      
    class DSL(x:Int){  
           def days(day:Day)={  
                  var can=Calendar.getInstance  
                  def backward():Unit=can.set(Calendar.DAY_OF_MONTH, can.get(Calendar.DAY_OF_MONTH)-x)  
                  def forward():Unit=can.set(Calendar.DAY_OF_MONTH, can.get(Calendar.DAY_OF_MONTH)+x)  
                  day match{  
                         case day:Backward => backward()  
                         case day:Forward => forward()  
                         case _ =>  
                  }  
                  DSL.formats(can.getTime)  
           }  
    }  
      
    object DSL{  
           implicit def intToDSL(x:Int)=DSL(x)  
           def apply(x:Int)=new DSL(x)  
           def formats(date:Date)=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)  
           def now=formats(Calendar.getInstance.getTime)+" => now..."  
             
           def main(args:Array[String]):Unit={  
                 println(now)  
                 println(2 days ago)  
                 println(3 days before)  
                 println(3 days after)  
                 println(4 days later)  
           }  
    }
环境2.8.1.final,另存为xxx.scala文件
编译>scala xxx.scala
运行>scala DSL

2010-12-12 17:57:04 => now...
2010-12-10 17:57:04
2010-12-09 17:57:04
2010-12-15 17:57:04
2010-12-16 17:57:04

用String做匹配当然可以,我感觉应该用Scala的本身特性来做介绍,这样更能吸引读者;
case class  用在模式匹配,可以用来构建(复杂)表达式;
case object 在actor模型里被当做消息用于模式匹配,当然还有别的功能; 


这个例子涉及到的知识点有:包引用,密封类,case object,隐式转换,模式匹配,函数,apply方法;
开始我是用case class,有点冗余,这里只是当做消息处理,于是改成case object;
解释一下,运行2 days ago这行代码,2是整型对象,它没有days方法,就会在执行的上下文里找一个隐式函数,这个隐式函数可以把整型对象转换成带有days方法的目标对 象,如果预导入的PreDef对象内也含有一个做到上述功能的隐式函数,那么编译器会认为这是冲突,无法编译:
Note that implicit conversions are not applicable because they are ambiguous
这里我认为,编译器应该优先去找用户自定义隐式函数,而不是报错,呵呵,那样的话编译器要做更多的工作了。

你可能感兴趣的:(Scala : 2 days ago)