Reputation: 595
Consider class with type parameter, that should be used as Map
key.
class Foo<K> {
var map: Map<K, Dynamic> = new Map();
}
This does not compile with error Type parameters of multi type abstracts must be known
.
The reason is understandable - Map
is abstract
and it's underlying type is selected based on key type, so key type should be known when compiling new Map()
expression. On the other hand non-generic type with type parameters are compiled once for all parameters.
Looks like adding @:generic
metadata should help. But actually it does not. My guess was that this is because haxe compiler compiles @:generic
types the same as it does with non-generic types, and only then does some extra work for generic type. So I was thinking that having a Map
with key type defined by type parameter is impossible in haxe.
But recently I've stumbled upon this issue: https://github.com/HaxeFoundation/haxe/issues/2537
Simn's answer there says, that this can be done by adding @:remove @:generic
metadata. And it actually works.
@:remove @:generic
class Foo<K> {
var map: Map<K, Dynamic> = new Map();
}
For me this looks like magic and I'm not comfortable with this. In documentation I only see that @:remove Causes an interface to be removed from all implementing classes before generation. That does not explain why this works.
Upvotes: 2
Views: 103
Reputation: 222
If you replace Map by haxe.ds.BalancedTree and use only @:generic without @:remove, you will see your class Foo generated on your target containing new BalancedTree< object, object > (object is Dynamic). That means, Foo class holds general BalancedTree< object, object > type, while Foo_String for example holds generic BalancedTree< string, object > type. Now, if you go back to your Map, you will see that "Abstract haxe.ds.Map has no @:to function that accepts haxe.IMap< Foo.K, Dynamic >", e.g. no Map< Dynamic, Dynamic > implementation exists. That's why you need to use @:remove which will actually stop generation of Foo class, or at least, remove new Map< Dynamic, Dynamic > from the Foo (@:remove "Causes an interface to be removed" is misleading here)
Upvotes: 3