使用 F# 的显式对象构造函数中的失败
下面的代码
type A (b) =
new () =
if true then A 4.
else failwith ""
给出了一个错误:
这不是有效的对象构造表达式。显式对象构造函数必须调用备用构造函数或初始化对象的所有字段并指定对超类构造函数的调用。
这有效:
type A (b) =
new () =
if true then A 4.
else failwith ""; A 4.
简单的问题。构造函数中的 failwith
有什么不好的地方?
The following code
type A (b) =
new () =
if true then A 4.
else failwith ""
gives an error:
This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor.
This works:
type A (b) =
new () =
if true then A 4.
else failwith ""; A 4.
Simple question. What is so bad about failwith
in the constructor?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题本身并不是
failwith
。正如错误所示,非主构造函数受到限制。这是为了鼓励将所有初始化逻辑放在主构造函数中。你的例子看起来很做作。如果您展示更多您正在尝试做的事情,也许有人可以提供解决方案。下面是重新编写代码的一种方法:
then
的作用类似于非主构造函数中的do
绑定。有关更多选项,请参阅有关构造函数的 MSDN 页面。
编辑
kvb 对于具有副作用的主构造函数提出了很好的观点。如果是这种情况,您可能需要考虑将逻辑转移到静态方法。这表明在调用构造函数之前可以完成其他工作。
The issue is not
failwith
per se. As the error indicates, non-primary constructors are restricted. This is to encourage putting all initialization logic in the primary constructor. Your example seems contrived. If you show more of what you're trying to do perhaps someone can offer a solution.Here's one way to rework your code:
then
acts like ado
binding in non-primary constructors.See the MSDN page on Constructors for more options.
EDIT
kvb made a good point regarding primary constructors with side effects. If that's the case you may want to consider moving your logic to a static method. This makes it obvious that other work may be done prior to calling the constructor.
您看到的问题并非特定于
failwith
;除了构造函数调用之外,任何其他A
类型的表达式也会发生这种情况,例如Unchecked.defaultof
。正如错误消息所示,构造函数对可在其中使用的表达式类型有限制,以确保类型始终正确初始化。正如我在对 Daniel 的回答的评论中提到的,如果您想在某些情况下快速失败,您可以执行以下操作:
这将在有机会执行链式构造函数调用之前抛出异常。
The problem you are seeing is not specific to
failwith
; it would also occur with any other expression of typeA
other than a constructor call, such asUnchecked.defaultof<A>
. As the error message indicates, constructors have restrictions on the kinds of expressions that can be used within them to ensure that types are always initialized soundly.As I mentioned in a comment on Daniel's answer, if you want to fail fast in certain cases you could do something like:
This will throw an exception before it gets a chance to execute the chained constructor call.