I tried to define a structural type which is matched to an instance with a generic type. Like in this example code:
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
}
but I get a compilation error:
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 = {
When I get rid of the generic type in the method and write the code like this:
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
}
it compiles but I get a runtime exception:
java.lang.NoSuchMethodException: java.util.HashSet.add(java.lang.String)
My question is: How to correctly define the structural type, so it can work with Java collections?
Note that it cannot replace them with Scala collection (it will be used with a Java library).