假设我有以下代码:
abstract class GenericType[T]{
val someSeq: Seq[T]
def list() = for(item <- someSeq) println(item)
}
class ConcreteType extends GenericType[Int] {
val someSeq = Seq(1, 2, 3)
}
object MyApp {
def main(args: Array[String]) {
val ct = new ConcreteType
ct.list()
}
}
这只是打印出1 2 3(在单独的行上)。但是假设我想要创建一个泛型类型的实例来调用T
的某个方法。例如,假设我想调用整数的max
方法。我如何指定要调用的方法?
我假设我可以在抽象类中创建一个值,该类包含在每个item
上调用的方法,并在具体类中指定该方法。
换句话说,我想最终得到类似的东西:
abstract class GenericType[T]{
val someSeq: Seq[T]
val methodToCall: ???
def list() = for(item <- someSeq) println(item.methodToCall)
}
class ConcreteType extends GenericType[SomeType] {
val someSeq = Seq(1, 2, 3)
val methodToCall = ???.max(_, 2)
}
并期望main
然后打印出2 2 3(即for(item <- someSeq) println(item.max(_, 2))
的结果)。
答案 0 :(得分:3)
你不能这样做。您只能返回值,方法不是值。但是,您可以使用函数并传递lambda或通过η-expansion将方法转换为函数。
abstract class GenericType[T] {
def someSeq: Seq[T]
type MapResult
def map: T => MapResult
def list() = someSeq.foreach(map andThen println)
}
class ConcreteType extends GenericType[Int] {
override val someSeq = Seq(1, 2, 3)
override type MapResult = Int
override val map = 2.max(_)
}
答案 1 :(得分:1)
我个人会尝试使用类型类。这是一个例子:
trait MethodToCall[T, R] {
def invoke(obj: T): R
}
implicit object IntToCall extends MethodToCall[Int, Int] {
override def invoke(obj: Int): Int = obj.max(2)
}
abstract class GenericType[T]{
def someSeq: Seq[T]
def list[R](implicit mtc: MethodToCall[T, R]) =
for(item <- someSeq) println(mtc.invoke(item))
}
class ConcreteType extends GenericType[Int] {
val someSeq = Seq(1, 2, 3)
}
new ConcreteType().list[Int]
答案 2 :(得分:0)
你需要指定'mtehodToCall'的返回类型,我使用T代表
abstract class GenericType[T]{
def someSeq: Seq[T]
def methodToCall: T => T
def list() = for(item <- someSeq) println(methodToCall(item))
}
class ConcreteType extends GenericType[Int] {
val someSeq = Seq(1, 2, 3)
val methodToCall: Int => Int = math.max(_, 2)
}
new ConcreteType().list()