Scala 2.10"没有隐含的视图和#34;请求视图的类型参数出错

时间:2018-06-15 17:56:14

标签: scala scala-2.10

我已经从一个更大的项目遇到的事情中减少了这个例子;基本问题似乎是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-only错误案例:

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

我不明白这里发生了什么:我没有尝试声明一个隐含的对象,我试图声明该类采用隐式参数。为什么第一堂课好,但第二堂课不好?

1 个答案:

答案 0 :(得分:3)

将参数类型参数A添加到Namer(在Subnamer继承中)为我工作(Scala版本2.10.7):

class SubNamer[A <% Nameish](e: Class[A]) extends Namer[A](e)

顺便说一句,没有修改的示例仅适用于Scala版本2.11.5。

希望这有帮助。