题
我正在尝试定义一个结构性类型,以定义具有“添加”方法的任何集合(例如,Java集合)。使用此功能,我想定义一些在某个集合上运行的高阶功能
object GenericTypes {
type GenericCollection[T] = { def add(value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection[X]] {
def map[V](fn: (T) => V): CollectionType[V]
....
}
class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
这不会与以下错误一起编译
error: Parameter type in structural refinement may not refer to abstract type defined outside that same refinement
我尝试在通用汇编时删除参数,并将其放在方法上:
object GenericTypes {
type GenericCollection = { def add[T](value: T): java.lang.Boolean}
}
import GenericTypes._
trait HigherOrderFunctions[T, CollectionType[X] <: GenericCollection]
class RichJList[T](list: List[T]) extends HigherOrderFunctions[T, java.util.List]
但是我得到了另一个错误:
error: type arguments [T,java.util.List] do not conform to trait HigherOrderFunctions's type parameter bounds [T,CollectionType[X] <: org.scala_tools.javautils.j2s.GenericTypes.GenericCollection]
谁能给我一些有关如何使用Scala中抽象键入参数使用结构键入的建议?还是如何实现我想要完成的目标?非常感谢!
解决方案
如您所见 票1906年 由于在运行时缺少类型信息,因此无法使用在结构类型之外定义的抽象类型。
Within a method declaration in a structural refinement, the type of
any value parameter may only refer to type parameters or abstract types that are
contained inside the refinement.
将新方法添加到类型的通常方法是通过隐式类型转换。
trait HigherOrderFunctions[T, CC[_]] {
def zap[V](fn: () => V): CC[V]
}
class RichJList[T](list: java.util.List[T]) extends HigherOrderFunctions[T, java.util.List]{
def zap[V](fn: () => V): java.util.List[V] = {
val l = new java.util.ArrayList[V]
l add fn()
l
}
}
implicit def list2RichList[T](l : java.util.List[T]) = new RichJList(l)
new java.util.ArrayList[AnyRef]() zap (() => 2)
如果编译器看到该类型错过了ZAP方法,则将其转换为具有范围内具有隐式转换方法(此处list2richlist)的ZAP方法的类型。
scala> new java.util.ArrayList[AnyRef]() zap (() => 2)
res0: java.util.List[Int] = [2]
不隶属于 StackOverflow