Scala 中具有泛型的结构类型
Structural types with generics in Scala
我试图定义一个结构类型,它与具有泛型类型的实例相匹配。就像在这个示例代码中一样:
class ExampleTest extends FlatSpec with Matchers {
def add[T](container: {def add(s: T): Boolean})(element: T): Unit = {
container.add(element)
}
val set = new java.util.HashSet[String]()
add(set)("3")
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list)("3")
list.contains("3") shouldEqual true
}
但是我得到一个编译错误:
Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def add[T](container: {def add(s: T): Boolean})(element: T): Unit = {
当我把方法中的泛型去掉,写成这样的代码时:
class ExampleTest extends FlatSpec with Matchers {
def add(container: {def add(s: String): Boolean}): Unit = {
container.add("3")
}
val set = new java.util.HashSet[String]()
add(set)
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list)
list.contains("3") shouldEqual true
}
它可以编译,但出现运行时异常:
java.lang.NoSuchMethodException: java.util.HashSet.add(java.lang.String)
我的问题是:
如何正确定义结构类型,以便它可以与 Java 集合一起使用?
请注意,它不能用 Scala 集合替换它们(它将与 Java 库一起使用)。
尝试
import scala.language.reflectiveCalls
def add[T](container: {def add(s: Any): Boolean})(element: T): Unit = {
container.add(element)
}
val set = new java.util.HashSet[String]()
add(set.asInstanceOf[{def add(s: Any): Boolean}])("3")
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list.asInstanceOf[{def add(s: Any): Boolean}])("3")
list.contains("3") shouldEqual true
java.util.HashSet#add
(实际上是java.util.AbstractCollection#add
)和java.util.LinkedList#add
的签名是
boolean add(E e)
结构类型的反射调用在运行时解决。在运行时,由于类型擦除泛型 E
只是 Any
(又名 Object
)。
我试图定义一个结构类型,它与具有泛型类型的实例相匹配。就像在这个示例代码中一样:
class ExampleTest extends FlatSpec with Matchers {
def add[T](container: {def add(s: T): Boolean})(element: T): Unit = {
container.add(element)
}
val set = new java.util.HashSet[String]()
add(set)("3")
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list)("3")
list.contains("3") shouldEqual true
}
但是我得到一个编译错误:
Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def add[T](container: {def add(s: T): Boolean})(element: T): Unit = {
当我把方法中的泛型去掉,写成这样的代码时:
class ExampleTest extends FlatSpec with Matchers {
def add(container: {def add(s: String): Boolean}): Unit = {
container.add("3")
}
val set = new java.util.HashSet[String]()
add(set)
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list)
list.contains("3") shouldEqual true
}
它可以编译,但出现运行时异常:
java.lang.NoSuchMethodException: java.util.HashSet.add(java.lang.String)
我的问题是: 如何正确定义结构类型,以便它可以与 Java 集合一起使用?
请注意,它不能用 Scala 集合替换它们(它将与 Java 库一起使用)。
尝试
import scala.language.reflectiveCalls
def add[T](container: {def add(s: Any): Boolean})(element: T): Unit = {
container.add(element)
}
val set = new java.util.HashSet[String]()
add(set.asInstanceOf[{def add(s: Any): Boolean}])("3")
set.contains("3") shouldEqual true
val list = new java.util.LinkedList[String]()
add(list.asInstanceOf[{def add(s: Any): Boolean}])("3")
list.contains("3") shouldEqual true
java.util.HashSet#add
(实际上是java.util.AbstractCollection#add
)和java.util.LinkedList#add
的签名是
boolean add(E e)
结构类型的反射调用在运行时解决。在运行时,由于类型擦除泛型 E
只是 Any
(又名 Object
)。