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;
}
但是我不喜欢这两种方法:
- 我不喜欢将 @:op(...) 添加到 MyBool,因为为每个可能的运算符创建一个方法需要很多代码(也许不需要布尔值,但例如使用 Int、Float 等) .
- 我不喜欢使用 !var.toBool()。如果某人已经编写了相当多的代码,那么他不想遍历所有代码,而当他只是想将 Bool 更改为 MyBool ...我的意思是他当然也可以将 Bool 转换为每当添加新代码时都添加到 MyBool,但这也很糟糕。
所以我想知道是否有人有更好的主意?是否还有另一个“@: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 通过静态扩展(记录在斧头手册)。这种方法将消除运营商转发的需要。
我正在尝试编写自己的带有一些附加功能的布尔值 "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;
}
但是我不喜欢这两种方法:
- 我不喜欢将 @:op(...) 添加到 MyBool,因为为每个可能的运算符创建一个方法需要很多代码(也许不需要布尔值,但例如使用 Int、Float 等) .
- 我不喜欢使用 !var.toBool()。如果某人已经编写了相当多的代码,那么他不想遍历所有代码,而当他只是想将 Bool 更改为 MyBool ...我的意思是他当然也可以将 Bool 转换为每当添加新代码时都添加到 MyBool,但这也很糟糕。
所以我想知道是否有人有更好的主意?是否还有另一个“@: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 通过静态扩展(记录在斧头手册)。这种方法将消除运营商转发的需要。