Внедряющий набор <T> - PullRequest
       26

Внедряющий набор <T>

0 голосов
/ 28 сентября 2018

Я пытаюсь обернуть голову вокруг 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();
  }
}

Компилятору это не нравится.Это говорит мне 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;
}

, а затем создаю экземпляр с var set = new Set(new Map());, это работает.

Это довольно грубо, хотя.Мне бы хотелось иметь возможность создавать экземпляры Sets без раскрытия базовой реализации.В конечном счете, я бы предпочел конструктор с подписью new(?initial:Iterable<T>).Это возможно?Я что-то неправильно понимаю?

1 Ответ

0 голосов
/ 28 сентября 2018

Проблема в том, что в настоящее время невозможно создать экземпляр Map без того, чтобы был известен тип ключа (а поскольку Set.T является параметром свободного типа, это не работает).Однако, так как конструктор inline, T может быть хорошо известно на сайте вызовов.Проблема в том, что компилятор все еще пытается сгенерировать Set.new.Вы можете избежать этого, добавив префикс @:extern.Рабочий пример: https://try.haxe.org/#1D06C

...