F# 如何在构造函数中引发异常?
如果我这样做,难道没有意义吗F# 如何在构造函数中引发异常?,f#,F#,如果我这样做,难道没有意义吗 type Point = struct val Row: int val Column: int new (row, column) = if row >= 0 && column >= 0 then { Row = row; Column = column } else failwith "Cooridinators mu
type Point =
struct
val Row: int
val Column: int
new (row, column) = if row >= 0 && column >= 0 then { Row = row; Column = column }
else failwith "Cooridinators must be non-negative!"
// This is not a valid object construction
static member (+) (x: Point, y: Point) = Point (x.Row + y.Row, x.Column + y.Column)
static member (-) (x: Point, y: Point) = Point (x.Row - y.Row, x.Column - y.Column)
static member (*) (x: Point, a) = Point (x.Row * a, x.Column * a)
static member (*) (a, x: Point) = Point (x.Row * a, x.Column * a)
end
如果它是一个类,那么也许我可以在do
绑定期间引发异常,但是在一个结构中没有do
,我应该怎么做
我发现有可能在failwith
之后添加另一个构造函数来解决这个问题,但它提出了另一个问题,我如何调用隐式构造函数?我必须先明确地构造它吗
new () = { Row = 0; Column = 0}
// Error structs auto supports a default constructor
如果我只是使用默认构造函数来实现这一点
new (row, column) = if row >= 0 && column >= 0 then { Row = row; Column = column }
else
failwith "Cooridinators must be non-negative!"
new Point () // error
在我看来,Point()
返回的是一个单位,而不是Point
?我认为F编译器会抱怨,因为构造函数应该总是有一个结构:
新建(
模式)=
表达式{
初始化}[然后表达式]
因此,初始化字段的部分不能嵌套在if
下或任何其他表达式中。您可以在初始化之前或之后抛出异常(如果添加然后
关键字)。(这对继承类很重要,但我认为这对结构没有任何影响。)
因此,编写代码的一种方法是:
type Point =
struct
val Row: int
val Column: int
new (row, column) =
if row < 0 || column < 0 then failwith "Cooridinators must be non-negative!"
{ Row = row; Column = column }
// (Static members omitted)
end
类型点=
结构
val行:int
val列:int
新建(行、列)=
如果行<0 | |列<0,则failwith“Cooridinator必须为非负!”
{行=行;列=列}
//(静态成员省略)
结束
请注意,我必须否定该条件,因为您需要在希望引发异常时指定大小写(而不是说何时可以构造对象)。另一种选择是:
new (row, column) =
{ Row = row; Column = column }
then if row < 0 || column < 0 then failwith "Cooridinators must be non-negative!"
new(行、列)=
{行=行;列=列}
然后,如果行<0 | |列<0,则failwith“Cooridinator必须为非负!”
在初始化部分,您可以使用另一种方法抛出异常:
new(行、列)=
{Row=(如果Row<0 | | column<0,则failwith“Coordinators must non-negative!”;Row);
列=列}
请记住,验证结构构造函数并不总是一个好主意。正如您所发现的,您无法控制默认构造函数的初始化。如果它是一个类,您可以确保所有构造函数都按照您想要的方式进行验证。这是一个老问题。然而,没有一个答案提到这一点:我认为惯用的F#way根本就不是抛出异常!为了实现这一点,您可以使用静态成员tryCreate
,如果所有条件都满足,它将返回某个点
,如果出现问题,则返回无
。然后,您将遵循选项类型的轨迹来编写逻辑代码,而不是处理异常!我还认为F#record可能也是一种更为惯用的方式,除非您出于某些非常特定的目的明确地需要struct
new (row, column) =
{ Row = ((if row < 0 || column < 0 then failwith "Coordinators must be non-negative!"); row);
Column = column }