无法在 F# 中重载布尔运算符
F# 确实允许重载算术运算符(如 +),但似乎不允许重载布尔运算符(如 ||)。以下代码生成一个警告和两个错误:
type MyBool =
val Value : bool
new(value) = { Value = value }
static member (||) (v1: MyBool, v2 : MyBool) =
new MyBool(v1.Value || v2.Value)
let b1 = new MyBool(true)
let b2 = new MyBool(false)
let b3 = b1 || b2
警告(关于静态成员 (||) 定义):名称“(||)”不应用作成员名称。如果定义静态成员以供其他 CLI 语言使用,则使用名称“op_BooleanOr”。
错误(在“let b3”语句中的 b1 和 b2 上):此表达式应具有 bool 类型,但此处具有 MyBool 类型。
如果我使用 op_BooleanOr 而不是 (||),则警告消失,但错误仍然存在。
当我对 MyInt 类型中的 + 运算符执行完全相同的操作时,没有警告或错误。那么,为什么当我尝试超载时会出现这些警告/错误 ||或&&?
F# does allow overloading of arithmetic operators like +, but seems to disallow this for boolean operators like ||. The following code generates a warning and two errors:
type MyBool =
val Value : bool
new(value) = { Value = value }
static member (||) (v1: MyBool, v2 : MyBool) =
new MyBool(v1.Value || v2.Value)
let b1 = new MyBool(true)
let b2 = new MyBool(false)
let b3 = b1 || b2
Warning (on the static member (||) definition): The name '(||)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name 'op_BooleanOr' instead.
Error (on b1 and b2 in the 'let b3' statement): This expression was expected to have type bool but here has type MyBool
If I use op_BooleanOr instead of (||) the warning disappears, but the errors remain.
When I do exactly the same thing for the + operator in a MyInt type there are no warnings or errors. So, why do these warnings/errors appear when I try to overload || or &&?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
恐怕 F# 编译器没有对逻辑运算符进行任何处理,允许您覆盖它们(就像 C# 那样)。据我所知,
x && y
简单地编译为if x then y else false
,因此x
必须是布尔值。我没有检查 F# 编译器是否支持 C# 中声明的类型的这种行为,但我认为不支持。据我所知,为您自己的运算符模拟短路行为的最佳方法是使用
lazy
关键字创建惰性值。然后您可以编写如下内容:这两个运算符可以使用静态成员约束来定义,因此它们(原则上)应该适用于实现 C# 所需运算符的任何类型。
然后,您可以使用所有必需的运算符定义您的
MyBool
类型(顺便说一下,如果您像这样定义它,它应该可以以 C# 的自然方式使用):I'm afraid that the F# compiler doesn't have any treatment of logical operators that would allow you to override them (as C# does). As far as I can tell,
x && y
is compiled simply asif x then y else false
, sox
has to be boolean. I didn't check whether the F# compiler supports this behavior for types declared in C#, but I don't think it does.As far as I know, the best way to emulate short-circuiting behvaior for your own operator is to use the
lazy
keyword to create lazy values. Then you can write something like:The two operators can be defined using static member constraints, so they should (in principle) work for any types that implement the operators required by C#.
Then you can define your
MyBool
types with all the required operators (as a side note, it should be usable in the natural way from C# if you define it like this):&&
和||
与其他运算符的不同之处在于它们是短路的,因此不能简单地实现为方法。因此 .net 定义了特殊规则 您需要按照以下步骤启用&&
和||
与您自己的类型的使用。简而言之:您还需要定义
operator true
和operator false
。&&
and||
differ from other operators in that they're short-circuiting and can thus not be implemented simply as methods. Because of this .net defines special rules you need to follow to enable the usage of&&
and||
with your own types.In short: you need to define
operator true
andoperator false
as well.