Scala:隐式参数中的错误
以下是我真正问题的简化版本:
class Z[T] object E extends Enumeration { implicit val z = new Z[Value] val X,Y = Value } implicit def f[T : Z] = (getter: T) => 0 implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0 def e: Option[E.Value] = null val b: Int = e 这是有效的,b隐式转换为o(e)(f(E.z)).但随着以下小变化: implicit def f[T : Z] = (setter: T => Unit) => 0 implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0 它找不到合适的隐含值E.z虽然与原始代码没有本质区别,但是手动显式转换为o(e)(f(E.z))仍然有效. 我知道隐式参数的实现还没有完成,还有很多未解决的问题.如果这是其中之一,我想向Scala贡献者报告.所以我的问题是,a)这真的是一个错误吗? b)如果是这样,我在哪里以及如何提交错误以便将来修复? UPDATE 特拉维斯的回答就像一个魅力!顺便说一下,上面的代码解决了我原来的问题: implicit object E extends Enumeration { val X,Y = Value } implicit object F extends Enumeration { val X,Y = Value } implicit def f[T <: Enumeration](getter: T#Value)(implicit e: T) = 0 implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0 val b: Int = Some[E.Value](null) 在这段代码中,情况恰恰相反:它适用于setter版本,但不适用于更简单的getter版本.编译器抱怨说使用E或F作为隐式参数是令人困惑的,尽管使用F实际上并不编译也没有意义.我通过做类似的事情设法让它工作: implicit def f[S <% T => T,T <: Enumeration](getter: T#Value)(implicit e: T) = 0 这是有效的,虽然我不知何故可以使它工作,但我仍然不理解这种魔法背后的逻辑. 解决方法
你已经遇到了另一个
this limitation Scala类型推理系统的变种.
如果在第一种情况下,编译器将解析T的f,它正在寻找从普通旧E.Value到Int的隐式转换,而不是在第二种情况下,它想要从E.Value =>转换.单位(即,Function1 [E.Value,Unit])到Int. 幸运的是,在这种情况下有一个简单的解决方法 – 只需使用视图绑定: implicit def f[F <% T => Unit,T: Z] = (setter: F) => 0 这将是以下类似的东西: implicit def f[F,T](implicit st: F <:< (T => Unit),ev: Z[T]) = (setter: F) => 0 现在当编译器想要从E.Value =>进行转换时单位到Int它将能够将F解析为E.Value =>单位立即然后T到E.Value. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- angular2-google-maps with angular2 app
- AngularJS:与服务器端验证集成
- Bootstrap模板代码+页面自适应页面的案例代码
- Bash学习笔记(1)-----bash初步及介绍
- angularjs – 使用ng-options上的过滤器更改显示的值
- 在Bash的静态HTML文件上运行jQuery
- Bootstrap Table笔记——1
- twitter-bootstrap – Bootstrap:在Breadcrumb中下拉
- AngularJS不在布尔模型字段的下拉列表中设置任何值
- (Angular Material)用Autocomplete打造带层级分类的DropD