我已经将这个例子从一个更大的项目中遇到的问题中减少了;基本的问题似乎是scala 2.10对视图约束的处理有点奇怪,或者可能会中断:
trait Nameish {
def name: String
}
abstract class Namer[A <% Nameish](e: Class[A]) {
def doNameThing(x: A) = println("argument is named " + x.name)
}
class SubNamer[A <% Nameish](e: Class[A]) extends Namer(e) {
}
object TestViews extends App {
import scala.language.implicitConversions
implicit def nameStr(x: String): Nameish = new StringNamer(x);
class StringNamer(x: String) extends Nameish {
def name = x
}
println(new SubNamer(classOf[String]).doNameThing("foo"))
}
当我试图编译这个时,在scala 2.10中我得到了错误:
TestViews.scala:8: error: No implicit view available from A => Nameish.
class SubNamer[A <% Nameish](e: Class[A]) extends Namer(e) {
^
TestViews.scala:18: error: value doNameThing is not a member of SubNamer[String]
println(new SubNamer(classOf[String]).doNameThing("foo"))
^
two errors found
请注意,scala 2.11可以使用此代码。
不幸的是,将此代码重新工具化到较新的scala版本将使此任务的规模激增。我需要找到一种方法,使现有的scala接受具有视图约束的类型参数的类层次结构。
另一种解决方法发现了不同的scala-2.10错误案例:
trait Nameish {
def name: String
}
abstract class Namer[A](e: Class[A])(implicit view: A => Nameish) {
def doNameThing(x: A) = println("argument is named " + x.name)
}
class SubNamer[A](e: Class[A])(implicit view: A => Nameish) extends Namer(e)(view) {
}
object TestViews extends App {
import scala.language.implicitConversions
implicit def nameStr(x: String): Nameish = new StringNamer(x);
class StringNamer(x: String) extends Nameish {
def name = x
}
println(new SubNamer(classOf[String]).doNameThing("foo"))
}
这只是用隐式参数替换视图约束。
使用这段代码,它再次可以很好地编译scala 2.11,但是在scala 2.10上:
TestViews.scala:8: error: `implicit' modifier cannot be used for top-level objects
class SubNamer[A](e: Class[A])(implicit view: A => Nameish) extends Namer(e)(view) {
^
one error found
我不明白这里发生了什么:我不是要声明一个隐式对象,我是要声明类接受一个隐式参数。为什么一等舱可以,而二等舱不行?