什么是鸭子类型(Duck Typing)?鸭子类型可解释为,如果一只动物,走起来像鸭子或者叫起来像鸭子,就可以把它当作鸭子。
在程序中,就是可以定义一个函数,其他任何具有这个函数的类型,都可以看成同一种类型的对象。具体看例子:
1 // 资源管理器 2 class ResourceManager{ 3 // 定义一个含有close方法的类型 4 type Closable = { 5 def close(); 6 } 7 8 //resources 维护着一堆资源引用 9 private val resources = new scala.collection.mutable.ListBuffer[Closable](); 10 11 //释放所有托管的资源 12 def release(){ 13 resources foreach { _.close } 14 } 15 16 def add(resource: Closable) = resources += resource 17 } 18 19 // Resource1表示一种资源类型,具有close方法 20 class Resource1{ 21 def close(){ 22 println("resource1 is closed"); 23 } 24 } 25 26 // Resource2表示另一种资源类型,也具有close方法 27 class Resource2{ 28 def close(){ 29 println("resource2 is closed"); 30 } 31 } 32 33 val manager = new ResourceManager 34 manager.add(new Resource1) 35 manager.add(new Resource2) 36 manager.release()
其中Resource1和Resource2都定义了def close(),所以可以将他们看成同一种类型,传递参数时,用鸭子类型实现,举例如下:
1 object ResourceManager{ 2 private val pool = new scala.collection.mutable.ListBuffer[{ def close(): Unit }]; 3 4 def borrowResource(): { 5 def close(): Unit 6 } = { 7 println("borrow a resource from pool"); 8 // 简单起见,这里直接new一个临时对象返回 9 new { 10 def close()= println(" close resource "); 11 } 12 } 13 14 def addResource(resource: { def close(): Unit } ) = { 15 println("add a resource to pool"); 16 pool += resource; 17 } 18 19 }
其中def borrowResource(): { def close(): Unit },这个函数的返回类型,就是鸭子类型{ def close(): Unit },表示定义了def close(): Unit的类型,其中
Unit表示该类型的返回值为特殊类型(类似于java中的void)
其中def addResource(resource: { def close(): Unit } ),这个函数的参数,是鸭子类型{ def close(): Unit }。之后,只要传进来一个定义了这个函数的类型,就可以了。
再举一个scala tour上的例子这样的做法比使用接口要好很多,因为可以不引入任何依赖。这个withClose方法单独编译,随处使用。
1 def withClose(closeAble: { def close(): Unit }, 2 op: { def close(): Unit } => Unit) { 3 try { 4 op(closeAble) 5 } finally { 6 closeAble.close() 7 } 8 } 9 10 class Connection { 11 def close() = println("close Connection") 12 } 13 14 val conn: Connection = new Connection() 15 withClose(conn, conn => 16 println("do something with Connection"))
def withClose(closeAble: { def close(): Unit }, op: { def close(): Unit } => Unit) 这个函数在使用close()之前,可以利用这个链接,做些其他操作。
参考链接:http://my.oschina.net/aiguozhe/blog/35880?catalog=115675
http://www.yankay.com/scala-tour-choiceness/
浙公网安备 33010602011771号