`
cloverprince
  • 浏览: 126873 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

隐式转换:Scala对Extension Method的回应

阅读更多
.NET有Extension Methods。当你:
using System.Linq;

然后,你的所有数组对象神奇般地“拥有”了Contains, Count, GroupBy, OrderBy等一系列“前所未有”的方法。你感觉你的“Array”类被人注入了额外的东西。

C#的Extension Method定义为静态方法。如果第一个参数加上了this修饰符,那么这个方法就被认为是Extension Method。该方法被加在this修饰的参数的类型上。

注意ShyBoyKissSupport.Kiss方法
using System;

namespace BoyKiss
{
	abstract class Child
	{
		public string name { get; set; }
		protected Child(string name)
		{
			this.name = name;
		}
	}
	
	class Boy : Child
	{
		public Boy(string name) : base(name) {}
		
		public void Kiss(Girl girl)
		{
			System.Console.WriteLine("{0} kisses {1}", name, girl.name);
			girl.OnKissed(this);
		}
	}
	
	class Girl : Child
	{
		public Girl(string name) : base(name) {}

		public void OnKissed(Child child)
		{
			System.Console.WriteLine("{0} is kissed by {1}", name, child.name);
		}
	}
	
	class ShyBoy : Child
	{
		public ShyBoy(string name) : base(name) {}
		// Kiss method is missing
	}
	
	static class ShyBoyKissSupport {
		public static void kiss(this ShyBoy me, Girl girl)
		{
			System.Console.WriteLine("{0} bravely kisses {1}", me.name, girl.name);
			girl.OnKissed(me);
		}
	}
	
	class MainClass
	{
		public static void Main(string[] args)
		{
			var b = new Boy("Bob");
			var g = new Girl("Alice");
			
			b.Kiss(g);
			
			var b2 = new ShyBoy("Peter");
			var g2 = new Girl("Wendy");
			
			b2.Kiss(g2);
		}
	}
}
/* 输出:
Bob kisses Alice
Alice is kissed by Bob
Peter bravely kisses Wendy
Wendy is kissed by Peter
*/


然后ShyBoy类就拥有了Kiss方法。

-----------------

下面讨论Scala语言。所涉及的问题域如下:
package boykiss

class Child(val name:String) {
}

class Boy(name:String) extends Child(name) {
	def kiss(girl: Girl) {
		println(name+" kisses "+girl.name);
		girl.onKissed(this);
	}
}

class Girl(name:String) extends Child(name) {
	def onKissed(child : Child) {
		println(name +" is kissed by " + child.name);
	}
}

class ShyBoy(name:String) extends Child(name) {
	// kiss method is missing.
}


注意到,这个ShyBoy类仍然没有kiss方法。我们需要一定的代码给他加上。

Scala没有Extension Method,但是有隐式类型转换。如果一个方法加上了implicit修饰符,那么它就认为是一个隐式转换方法。如下:
object ShyBoyKissSupport {
	implicit def fromShyBoy(b : ShyBoy) = new ShyBoyWrapper(b);
}

class ShyBoyWrapper(me: ShyBoy) {
	def kiss(girl: Girl) {
		println(me.name+" bravely kisses "+girl.name);
		girl.onKissed(me); 
	}	
}

object定义了单例对象ShyBoyKissSupport。它的fromShyBoy方法有implicit修饰,因此会自动把ShyBoy对象用该方法转换成ShyBoyWrapper类的对象。

ShyBoyWrapper类只不过是一个封装器,封装了一个ShyBoy。它具有kiss方法。

主程序这样写:
import ShyBoyKissSupport.fromShyBoy

object Main {

	def main(args : Array[String]) {
		val b = new Boy("Bob");
		val g = new Girl("Alice");
		
		b.kiss(g);
		
		val b2 = new ShyBoy("Peter");
		val g2 = new Girl("Wendy");
		
		b2.kiss(g2);
	}

}
/* 输出:
Bob kisses Alice
Alice is kissed by Bob
Peter bravely kisses Wendy
Wendy is kissed by Peter
*/

这个import ShyBoyKissSupport.fromShyBoy在这里是必要的,否则在下面的代码中,这个隐式转换方法不可见,也就不能自动隐式转换。实际中还可以用package object完成这个工作。

当调用b2.kiss(g2)的时候,因为b2没有kiss方法,但有隐式转换函数fromShyBoy,而且ShyBoyWrapper有kiss方法。所以,b2会先被隐式转换成ShyBoyWrapper,然后调用ShyBoyWrapper.kiss方法。


总结:Scala的隐式转换可以完成类似Extension Method的功能。

分享到:
评论

相关推荐

    scala-java8-compat_2.11-0.7.0-API文档-中文版.zip

    赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...

    scala-xml_2.12-1.0.6-API文档-中文版.zip

    赠送jar包:scala-xml_2.12-1.0.6.jar; 赠送原API文档:scala-xml_2.12-1.0.6-javadoc.jar; 赠送源代码:scala-xml_2.12-1.0.6-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.12-1.0.6.pom; 包含翻译后的API...

    scala-parser-combinators-2.11-1.0.4-API文档-中文版.zip

    赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 赠送Maven依赖信息...

    scala-xml_2.11-1.0.4-API文档-中英对照版.zip

    赠送jar包:scala-xml_2.11-1.0.4.jar; 赠送原API文档:scala-xml_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.4-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.4.pom; 包含翻译后的API...

    scala-xml_2.11-1.0.5-API文档-中英对照版.zip

    赠送jar包:scala-xml_2.11-1.0.5.jar; 赠送原API文档:scala-xml_2.11-1.0.5-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.5-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.5.pom; 包含翻译后的API...

    scala-parser-combinators_2.11-1.0.4-API文档-中英对照版.zip

    赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 包含翻译后的API...

    scala-compiler-2.11.12-API文档-中文版.zip

    赠送jar包:scala-compiler-2.11.12.jar; 赠送原API文档:scala-compiler-2.11.12-javadoc.jar; 赠送源代码:scala-compiler-2.11.12-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.12.pom; 包含...

    scala-compiler-2.12.7-API文档-中文版.zip

    赠送jar包:scala-compiler-2.12.7.jar; 赠送原API文档:scala-compiler-2.12.7-javadoc.jar; 赠送源代码:scala-compiler-2.12.7-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.12.7.pom; 包含翻译后...

    scala-compiler-2.11.8-API文档-中英对照版.zip

    赠送jar包:scala-compiler-2.11.8.jar; 赠送原API文档:scala-compiler-2.11.8-javadoc.jar; 赠送源代码:scala-compiler-2.11.8-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.8.pom; 包含翻译后...

    scala-compiler-2.11.0-API文档-中文版.zip

    赠送jar包:scala-compiler-2.11.0.jar; 赠送原API文档:scala-compiler-2.11.0-javadoc.jar; 赠送源代码:scala-compiler-2.11.0-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.0.pom; 包含翻译后...

    scala-reflect-2.12.10-API文档-中文版.zip

    赠送jar包:scala-reflect-2.12.10.jar; 赠送原API文档:scala-reflect-2.12.10-javadoc.jar; 赠送源代码:scala-reflect-2.12.10-sources.jar; 赠送Maven依赖信息文件:scala-reflect-2.12.10.pom; 包含翻译后...

    scala-reflect-2.12.7-API文档-中文版.zip

    赠送jar包:scala-reflect-2.12.7.jar; 赠送原API文档:scala-reflect-2.12.7-javadoc.jar; 赠送源代码:scala-reflect-2.12.7-sources.jar; 赠送Maven依赖信息文件:scala-reflect-2.12.7.pom; 包含翻译后的API...

    scala-reflect-2.11.12-API文档-中英对照版.zip

    赠送jar包:scala-reflect-2.11.12.jar; 赠送原API文档:scala-reflect-2.11.12-javadoc.jar; 赠送源代码:scala-reflect-2.11.12-sources.jar; 赠送Maven依赖信息文件:scala-reflect-2.11.12.pom; 包含翻译后...

    scala-compiler-2.11.0-API文档-中英对照版.zip

    赠送jar包:scala-compiler-2.11.0.jar; 赠送原API文档:scala-compiler-2.11.0-javadoc.jar; 赠送源代码:scala-compiler-2.11.0-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.11.0.pom; 包含翻译后...

    scala-xml_2.11-1.0.5-API文档-中文版.zip

    赠送jar包:scala-xml_2.11-1.0.5.jar; 赠送原API文档:scala-xml_2.11-1.0.5-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.5-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.5.pom; 包含翻译后的API...

    scala-compiler-2.12.7-API文档-中英对照版.zip

    赠送jar包:scala-compiler-2.12.7.jar; 赠送原API文档:scala-compiler-2.12.7-javadoc.jar; 赠送源代码:scala-compiler-2.12.7-sources.jar; 赠送Maven依赖信息文件:scala-compiler-2.12.7.pom; 包含翻译后...

    scala-parser-combinators_2.12-1.1.0-API文档-中英对照版.zip

    赠送jar包:scala-parser-combinators_2.12-1.1.0.jar; 赠送原API文档:scala-parser-combinators_2.12-1.1.0-javadoc.jar; 赠送源代码:scala-parser-combinators_2.12-1.1.0-sources.jar; 赠送Maven依赖信息...

    scala-reflect-2.11.8-API文档-中文版.zip

    赠送jar包:scala-reflect-2.11.8.jar; 赠送原API文档:scala-reflect-2.11.8-javadoc.jar; 赠送源代码:scala-reflect-2.11.8-sources.jar; 赠送Maven依赖信息文件:scala-reflect-2.11.8.pom; 包含翻译后的API...

    scala-parser-combinators_2.12-1.1.0-API文档-中文版.zip

    赠送jar包:scala-parser-combinators_2.12-1.1.0.jar; 赠送原API文档:scala-parser-combinators_2.12-1.1.0-javadoc.jar; 赠送源代码:scala-parser-combinators_2.12-1.1.0-sources.jar; 赠送Maven依赖信息...

    scala-xml_2.11-1.0.1-API文档-中文版.zip

    赠送jar包:scala-xml_2.11-1.0.1.jar; 赠送原API文档:scala-xml_2.11-1.0.1-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.1-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.1.pom; 包含翻译后的API...

Global site tag (gtag.js) - Google Analytics