2

我是 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} 不采用类型参数 case class A[T: {def mkString(): String}](i: T)

错误:(4, 14) 值 mkString 不是类型参数 T val s = i.mkString 的成员

我正在使用 Scala 2.11.6。

任何帮助将不胜感激!谢谢 !

4

2 回答 2

2

type bounds[A : B]是一种简写方式,表示存在Btype 的 typeclass 的一个实例A,因此它们是等价的:

def foo[A : B]: C

def foo[A](implicit b: B[A]): C

您可能正在寻找的语法是[A <: B],这意味着A必须是B.

但是,您遇到的问题mkString实际上不在Array课堂上;如文档中所述,它在ArrayOps(通过隐式转换Array)中定义:

该成员是通过 Scala.Predef 中的 genericArrayOps 方法执行的从 Array[T] 到 ArrayOps[T] 的隐式转换添加的。

您可以通过以下方式解决此问题:

val a = "abc".toCharArray

case class A[T](i: T)(implicit conv: T => {def mkString: String}) {
  val s = conv(i).mkString
}

A(a)
于 2018-07-20T18:43:24.070 回答
1

至少有三个错误:

  1. 应该是<:,不是:。结构类型不是类型类。
  2. def mkString(): String不一样def mkString: String
  3. 原始 JVM 数组对方便的 scala 方法一无所知,例如mkString. 你需要一个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])
于 2018-07-20T18:45:08.923 回答