Scala 2.10 "No implicit view available" 请求视图的类型参数错误
Scala 2.10 "No implicit view available" error on type parameter that asks for a view
我已经从一个更大的项目中遇到的事情中减少了这个例子;根本问题似乎是 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 接受一个 class 层次结构,其类型参数具有视图约束。
另一种解决方法的尝试发现了一个不同的仅限 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
我不明白这是怎么回事:我不是要声明隐式对象,而是要声明 class 采用隐式参数。为什么第一个 class 没问题,而第二个就不行?
将参数类型参数 A
添加到 Namer
(在 Subnamer
继承中)对我有用(Scala 版本 2.10.7):
class SubNamer[A <% Nameish](e: Class[A]) extends Namer[A](e)
顺便说一下,您的示例未经修改仅适用于 Scala 版本 2.11.5。
希望对您有所帮助。
我已经从一个更大的项目中遇到的事情中减少了这个例子;根本问题似乎是 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 接受一个 class 层次结构,其类型参数具有视图约束。
另一种解决方法的尝试发现了一个不同的仅限 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
我不明白这是怎么回事:我不是要声明隐式对象,而是要声明 class 采用隐式参数。为什么第一个 class 没问题,而第二个就不行?
将参数类型参数 A
添加到 Namer
(在 Subnamer
继承中)对我有用(Scala 版本 2.10.7):
class SubNamer[A <% Nameish](e: Class[A]) extends Namer[A](e)
顺便说一下,您的示例未经修改仅适用于 Scala 版本 2.11.5。
希望对您有所帮助。