实现Set <T>

Mic*_*ael 6 haxe abstract

我试图abstract通过实现Set数据类型来解决这个问题,如下所示:

abstract Set<T>(Map<T, Bool>) {
  public inline function new() {
    this = new Map<T, Bool>();
  }

  public inline function has(item:T):Bool {
    return this.exists(item);
  }

  public inline function add(item:T):Set<T> {
    this.set(item, true);
    return null;
  }

  public inline function remove(item:T):Set<T> {
    this.remove(item);
    return null;
  }

  public inline function iterator():Iterator<T> {
    return this.keys();
  }
}
Run Code Online (Sandbox Code Playgroud)

但编译器并不喜欢这样.它告诉我Set.hx:8: characters 11-29 : Abstract Map has no @:to function that accepts IMap<util.Set.T, Bool>

我根本不理解这一点,因为如果我将构造函数更改为

public inline function new(val:Map<T, Bool>) {
  this = val;
}
Run Code Online (Sandbox Code Playgroud)

然后实例化var set = new Set(new Map());,它的工作原理.

但这非常糟糕.我希望能够在不暴露底层实现的情况下实例化集合.最后,我更喜欢带签名的构造函数new(?initial:Iterable<T>).这可能吗?我误会了什么吗?

bac*_*dos 7

问题是,如果Map没有密钥类型被识别,目前不可能实例化(因为它Set.T是一个自由类型参数,这不起作用).但是,由于构造函数是inline,T在调用站点可能是已知的.问题是编译器仍然试图生成Set.new.您可以通过为其添加前缀来避免这种情况@:extern.工作示例:https://try.haxe.org/#1D06C