如何在构造函数中抛出异常?

col*_*ang 4 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 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
Run Code Online (Sandbox Code Playgroud)

如果它是一个类,那么也许我可以在do绑定期间引发异常,但在结构中没有do,我该怎么办?

我发现之后可以添加另一个构造函数failwith来解决这个问题,但它引发了另一个问题,我怎样才能调用隐式构造函数?我是否必须首先明确地构建它

new () = { Row = 0; Column = 0} 
// Error structs auto supports a default constructor
Run Code Online (Sandbox Code Playgroud)

如果我只是使用默认构造函数执行此操作

new (row, column) = if row >= 0 && column >= 0 then { Row = row; Column = column }
                    else
                        failwith "Cooridinators must be non-negative!"
                        new Point () // error
Run Code Online (Sandbox Code Playgroud)

在我看来,Point ()返回一个单位,而不是Point

Tom*_*cek 9

我认为F#编译器会抱怨因为构造函数应该总是有一个结构:

new ( 模式 ) = 表达式 { 初始化 } [then 表达 ]

因此,初始化字段的部分不能嵌套在if任何其他表达式之下或之内.您可以在初始化之前或之后(如果添加then关键字)抛出异常.(这对于具有继承的类很重要,但我认为它对结构没有任何影响.)

因此,编写代码的一种方法是编写:

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
Run Code Online (Sandbox Code Playgroud)

请注意,我必须否定条件,因为您需要在要抛出异常时指定大小写(而不是说何时可以构造对象).另一种选择是:

new (row, column) = 
  { Row = row; Column = column }          
  then if row < 0 || column < 0 then failwith "Cooridinators must be non-negative!"
Run Code Online (Sandbox Code Playgroud)