【问题标题】:Scala 2.10 "No implicit view available" error on type parameter that asks for a view要求视图的类型参数上的 Scala 2.10“没有可用的隐式视图”错误
【发布时间】:2018-06-15 17:56:14
【问题描述】:

我已经从一个更大的项目中遇到的例子中简化了这个例子;根本问题似乎是 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

我不明白这里发生了什么:我不是要声明一个隐式对象,而是要声明该类采用隐式参数。为什么第一堂课可以,第二堂课不行?

【问题讨论】:

    标签: scala scala-2.10


    【解决方案1】:

    将参数类型参数A 添加到Namer(在Subnamer 继承中)对我有用(Scala 版本 2.10.7):

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

    顺便说一句,您的示例未经修改仅适用于我的 Scala 版本 2.11.5。

    希望这会有所帮助。

    【讨论】:

    • 关于哪个是第一个使用该代码的 scalac 的信息帮助我将其归结为 bug github.com/scala/bug/issues/3439 的表现形式,scalac 2.10 系列有这个 bug 并且没有当时很在意,但是……好吧。我最终以不同的方式解决了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多