作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我没有在任何地方定义函数ev
。那么,下面的代码是如何工作的呢?隐式是否必须在范围内的某处定义才能使用?
def same[T, U](x: U)(implicit ev: U => T): T = {ev(x)}
same(2) // 2
最佳答案
任何时候你有这样的问题,一个好的开始是使用 REPL 中的 Scala 反射 API 来询问编译器发生了什么:
scala> import scala.reflect.runtime.universe.{ reify, showCode }
import scala.reflect.runtime.universe.{reify, showCode}
scala> def same[T, U](x: U)(implicit ev: U => T): T = ev(x)
same: [T, U](x: U)(implicit ev: U => T)T
scala> showCode(reify(same(2)).tree)
res0: String = $read.same(2)(Predef.$conforms)
所以 ev
由 Predef.$conforms
提供, 一个隐式方法,它会给你一个 A <:< A
的实例对于任何 A
, 其中 <:<
延伸Function1
.
这是一个线索。弄清楚其余部分需要稍微考虑一下类型推断。当您调用 same(2)
,编译器计算出表达式 2
类型为 Int
,并推断出 U
是Int
.接下来它需要弄清楚是什么 T
是,为此它会从 Int
中寻找隐式函数至 x
对于某些类型 x
.
这是$conforms
的地方进来。它是范围内唯一的这样的方法,所以编译器选择它,这意味着 ev
类型为 Int => Int
和 T
必须是 Int
,你就完成了。
关于scala - 传递和使用隐式函数而不定义它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39944632/
我是一名优秀的程序员,十分优秀!