【发布时间】:2025-12-26 18:55:06
【问题描述】:
我想像这样在 Map 中使用函数作为键:
var timers : Map<Void->Void, snow.api.Timer>;
但 Haxe 不会编译:
抽象地图没有接受 IMap
的 @:to 函数Void, snow.api.Timer>
有没有办法做到这一点?
【问题讨论】:
标签: haxe
我想像这样在 Map 中使用函数作为键:
var timers : Map<Void->Void, snow.api.Timer>;
但 Haxe 不会编译:
抽象地图没有接受 IMap
的 @:to 函数Void, snow.api.Timer>
有没有办法做到这一点?
【问题讨论】:
标签: haxe
编写自定义实现很容易:
import haxe.Constraints;
class FunctionMap<K:Function,V> implements IMap<K,V> {
private var _keys : Array<K>;
private var _values : Array<V>;
public function new () {
_keys = [];
_values = [];
}
public function get(k:K):Null<V> {
var keyIndex = index(k);
if (keyIndex < 0) {
return null;
} else {
return _values[keyIndex];
}
}
public function set(k:K, v:V):Void {
var keyIndex = index(k);
if (keyIndex < 0) {
_keys.push(k);
_values.push(v);
} else {
_values[keyIndex] = v;
}
}
public function exists(k:K):Bool {
return index(k) >= 0;
}
public function remove(k:K):Bool {
var keyIndex = index(k);
if (keyIndex < 0) {
return false;
} else {
_keys.splice(keyIndex, 1);
_values.splice(keyIndex, 1);
return true;
}
}
public function keys():Iterator<K> {
return _keys.iterator();
}
public function iterator():Iterator<V> {
return _values
.iterator();
}
public function toString():String {
var s = new StringBuf();
s.add("{");
for( i in 0..._keys.length ) {
s.add('<function>');
s.add(" => ");
s.add(Std.string(_values[i]));
if( i < _keys.length - 1 )
s.add(", ");
}
s.add("}");
return s.toString();
}
private function index(key:K) : Int {
for (i in 0..._keys.length) {
if (Reflect.compareMethods(key, _keys[i])) {
return i;
}
}
return -1;
}}
【讨论】:
我刚刚在 try.haxe.org 中尝试过,编译器似乎不喜欢它,所以我猜答案是“不”。
您可以通过一些cleverness 来解决这个问题:
class Test {
static function main() {
var map:Map<VoidVoid,String>;
map = new Map<VoidVoid,String>();
var thing = {func:foo};
map.set(thing,"bar");
trace(map.get({func:foo})); //fails
trace(map.get(thing)); //succeeds;
}
static function foo():Void
{
}
}
typedef VoidVoid = {
var func:Void->Void;
}
但这不是一个理想的解决方案,因为如果它不是完全相同的实例,将它包装在一个 typedef 中会导致它失败,即使里面的值是相同的。
我也尝试过创建Map<Dynamic,String>,因为您可以在其中填充函数引用,但这也不起作用。
此时我应该问,你想用这种方式解决什么问题?或许可以通过其他方式更好地解决。
【讨论】: