我是Scala编程的新手,所以如果这是一个愚蠢的问题,请多多包涵。由于a
有一个mkString
方法,我期望下面的代码能工作。
val a = "abc".toCharArray
case class A[T: {def mkString(): String}](i: T) {
val s = i.mkString
}
A(a)
但是会出现以下错误:
错误:(3,16)AnyRef {def mkString():String}没有采用类型 参数案例类A [T:{def mkString():String}](i:T)
错误:(4,14)值mkString不是类型参数T val的成员 s = i.mkString
我正在使用Scala 2.11.6。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:2)
类型边界[A : B]
是表示存在类型B
的类型类A
实例的一种简写方式,因此它们是等效的:
def foo[A : B]: C
def foo[A](implicit b: B[A]): C
您可能正在寻找的语法是[A <: B]
,这意味着A
必须是B
的子类。
但是随后您遇到的问题是mkString
实际上不在Array
类中;如文档中所述,它是在ArrayOps
中定义的(从Array
起隐式转换):
此成员通过从Array [T]隐式转换为 ArrayOps [T]由scala.Predef中的genericArrayOps方法执行。
您可以通过以下方法解决此问题:
val a = "abc".toCharArray
case class A[T](i: T)(implicit conv: T => {def mkString: String}) {
val s = conv(i).mkString
}
A(a)
答案 1 :(得分:1)
那里至少有三个错误:
<:
,而不是:
。结构类型不是类型类。def mkString(): String
与def mkString: String
不同。mkString
之类的方便Scala方法一无所知。为此,您需要一个WrappedArray
。这在这里有效:
import scala.language.reflectiveCalls
val a = "abc".toCharArray
import collection.mutable.WrappedArray
case class A[T <: { def mkString: String }](i: T){
val s = i.mkString
}
A(a: WrappedArray[Char])