我正在尝试创建一个haxe.ds.HashMap
,其中键是我无法控制的对象。因此,他们没有实现hashCode
方法,我无法将它们更改为。
我真的想用一个抽象来完成这个,但是我得到了一些编译时错误。
Here is the code我正在玩:
import haxe.ds.HashMap;
abstract IntArrayKey( Array<Int> ) from Array<Int> {
inline public function new( i: Array<Int> ) {
this = i;
}
public function hashCode(): Int {
// General warning: Don't copy the following line. Seriously don't.
return this.length;
}
}
class Test {
static function main() {
var hash = new HashMap<IntArrayKey, Bool>();
}
}
编译错误是:
Test.hx:15: characters 19-51 : Constraint check failure for haxe.ds.HashMap.K
Test.hx:15: characters 19-51 : IntArrayKey should be { hashCode : Void -> Int }
但是当我change my abstract over to a class时,它编译得很好:
import haxe.ds.HashMap;
class IntArrayKey {
private var _i: Array<Int>;
inline public function new( i: Array<Int> ) {
this._i = i;
}
public function hashCode(): Int {
// General warning: Don't copy the following line. Seriously don't.
return this._i.length;
}
}
class Test {
static function main() {
var hash = new HashMap<IntArrayKey, Bool>();
}
}
这是完全相同的hashCode
实现,只是一个不同的上下文。有没有办法实现这个目标?还是语言限制?
答案 0 :(得分:2)
据我所知,摘要目前不能满足这样的类型要求,引用代码:
abstract HashMap<K:{ function hashCode():Int; }, V >(HashMapData<K,V>) {
所以,我怀疑你能以一种有意义的方式做到这一点。
重要的一点是,虽然摘要有时可以提供无开销的抽象,这对于优化非常有用,但实例化所需的时间(可能隐藏在abstract Name(Holder) to Holder
@:from
Array<Int>
@:to
和Array<Int>
{{1}})数组的持有者将拥有所需的方法并不高(与通常的运行时开销相比),除非它是一个非常频繁的代码,应该是你的第一种方式去吧。
然而,HashMap代码本身非常简短:here。 您可以复制它并使其与您的示例一起使用。也许你甚至可以通过使用接口来打造更好的通用版本(虽然我不确定摘要是否可以实际实现它们。)