hax 中的前向运算符

Forward operators in haxe

我正在尝试编写自己的带有一些附加功能的布尔值 "abstract"。

@forward
abstract MyBool(Bool) {
  public inline function new(b:Bool) {
    this = b;
  }
  @:from
  public static inline function fromBool(b:Bool):MyBool {
    return new MyBool(b);
  }
  @:to
  public inline function toBool():Bool {
    return this;
  }
  // some additional functions
}

原则上这很好用:

var t:T = true;
if(t) {
  trace("1");
}
t.someStrangeMethod();

但是@:forward 不会转发像“!”这样的基本布尔运算符:

var f:T = false;
if(!f) { // fails here, because "!" is not defined as an operator for MyBool ...
  trace("2");
}

错误信息是"MyBool should be Bool",我觉得很奇怪,因为MyBool是一个带有@:forward注解的Bool的抽象and有一个@:to -方法。

当然有一些简单的解决方法。可以使用:

if(!f.toBool()) {
  trace("2");
}

and/or 在摘要中添加一个注解为@:op(!A) 的函数:

@:op(!A)
public inline function notOp():Bool {
  return !this;
}

但是我不喜欢这两种方法:

所以我想知道是否有人有更好的主意?是否还有另一个“@:forward”之类的编译元数据,我还不知道?

有一个关于此的开放功能请求:

Can @:forward also forward underlying operator overloads? (#5035)

使您的代码示例正常工作的一种方法是允许使用 to Bool 进行隐式转换。我不完全确定为什么等效的 @:to 函数在这里不起作用,因为 Haxe 手册指出 "Class field casts have the same semantics".

abstract MyBool(Bool) to Bool {

除此之外,我认为唯一的选择是为每个要支持的运算符声明一个 @:op 函数。如果在没有主体的情况下声明,将转发基础类型的运算符:

@:op(!A) function notOp():MyBool;

如果您的主要目标只是向 Bool 类型添加方法,那么或许可以通过创建一个 class 来完全避免该问题,该 class 通过静态扩展(记录在斧头手册)。这种方法将消除运营商转发的需要。