`
wbj0110
  • 浏览: 1549761 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

scala隐式参数(implicit)

阅读更多
SBinary 和 Scalacheck的一部分库,广泛使用了隐式参数。让人联想起了Haskell(一种函数式编程语言)的编程风格,我真心的希望在Scala中这种编程风格更加广泛。这是一种非常有用的技术。

作为开始如下多重入参(柯里化)的例子:

scala -> def foo(x: Int)(y: Int) = x+y

foo: (x: Int)(y: Int) Int

 

scala -> foo (1) (2)

ret0:Int = 3

scala> foo(1, 2);
:6: error: wrong number of arguments for method foo: (Int)(Int)Int
       foo(1, 2);
       ^

scala> foo(1)
:6: error: missing arguments for method foo in object $iw;
follow this method with `_' if you want to treat it as a partially applied funct
ion
       foo(1)

上面你完全可以用单一函数的入参列表来调用它,但是你必须用不同的语法来调用它(两个挎号)

有一种方式你可以申明最后一个参数为隐式(implicit),不需要显式的传递。语法如下:
scala> def speakImplicitly (implicit greeting : String) = println(greeting)
speakImplicitly: (implicit String)Unit

scala> speakImplicitly("Goodbye world")
Goodbye world

scala> speakImplicitly
:6: error: no implicit argument matching parameter type String was foud.

scala> implicit val hello = "Hello world"
hello: java.lang.String = Hello world

scala> speakImplicitly
Hello world

你可以正常调用,也可以不传参数,系统将从作用域中找到一个被标示为
implicit变量,如果找不到implicit变量,编译的时候将会报错。

隐式变量的查找是强制类型匹配的,下面是一些例子展现:
错误的类型:

 

scala> def speakImplicitly (implicit greeting : String) = println(greeting)
speakImplicitly: (implicit String)Unit

scala> implicit val aUnit = ();
aUnit: Unit = ()

scala> speakImplicitly
:7: error: no implicit argument matching parameter type String was found.
只有String类型的隐式变量才能够匹配。

错误的泛型:
scala> def speakImplicitly (implicit greeting : String) = println(greeting)
speakImplicitly: (implicit String)Unit

scala> implicit val hello : Any = "Hello world"
hello: Any = Hello world

scala> speakImplicitly
:7: error: no implicit argument matching parameter type String was found.
隐式参数匹配必须是静态类型,泛型不能够匹配。

多个相同类型的参数:
scala> def speakImplicitly (implicit greeting : String) = println(greeting)
speakImplicitly: (implicit String)Unit

scala> implicit val foo = "foo";
foo: java.lang.String = foo

scala> implicit val bar = "bar";
bar: java.lang.String = bar

scala> speakImplicitly
:9: error: ambiguous implicit values:
 both value bar in object $iw of type => java.lang.String
 and value foo in object $iw of type => java.lang.String
 match expected type String
系统找到两个隐式参数是相同的类型,将无法识别。

子类可以匹配,
scala> def sayThings (implicit args : List[Any]) = args.foreach(println(_))
sayThings: (implicit List[Any])Unit

scala> implicit val nothingNiceToSay : List[Any] = Nil
nothingNiceToSay: List[Any] = List()

scala> sayThings

scala> implicit val hellos : List[String] = List("Hello world");
hellos: List[String] = List(Hello world)

scala> sayThings
Hello world

String作为Any的子类,所以系统可以匹配到

http://blog.csdn.net/yangguo_2011/article/details/41849537

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics