代码之家  ›  专栏  ›  技术社区  ›  Franco Tiveron

具有特殊结构特征的F类

f#
  •  4
  • Franco Tiveron  · 技术社区  · 7 年前

    我有一个类类型定义如下:

    type T1(?maybei1: int, ?maybei2: int) =
    

    所有以下工作:

    let t11 = T1(1, 2)
    let t12 = T1(1)
    let t13 = T1()
    

    但这次没有(如预期的那样):

    let tuple = (1, 2)
    let t14 = T1 tuple //error: expected int but given int * int
    

    另一方面,如果我将我的类型定义为:

    type T2(i1: int, i2: int) =
    

    然后我可以用元组构造一个实例

    let tuple = (1, 2)
    let t24 = T2 tuple //ok
    

    但我失去了选择:

    let t22 = T2(1) //error
    let t23 = T2() //error
    

    我尝试了另一个构造函数:

    type T3(?maybei1: int, ?maybei2: int) =
        new (i1: int, i2: int) = T3(i1, i2)
    
    type T4(i1: int, i2: int) =
        new (?maybei1: int, ?maybei2: int) =
    

    但是我不能得到一个可以用可选参数和元组实例化的版本。 有什么想法吗(没有委托、封装或继承,只有一种类型)?

    编辑

    托马斯佩特里切克找到了一种方法让它发挥作用;足够好了。

    然而,正如他也提到的,还有一些事情,imho,听起来并不完全正确。 例如,如果没有采用元组的重载构造函数,我们最终会出现以下情况:

    let tup = (1, 2)
    
    let t1 = T (1, 2) //ok
    let t2 = T tup //error
    

    在第一个实例化中,编译器将这两个参数映射为构造函数所期望的选项类型,我希望在第二个实例化中也会发生同样的情况。 有人知道这不是为什么吗?

    1 回复  |  直到 7 年前
        1
  •  8
  •   Tomas Petricek    7 年前

    如果添加了一个重载构造函数,该构造函数只接受显式元组作为其参数,则创建实例的所有方法都可以工作:

    type T(?maybei1: int, ?maybei2: int) =
        new (tup:int*int) = T(fst tup, snd tup)
        member x.Values = maybei1, maybei2
    
    T(1)
    T(1, 2)
    T(maybei2=2)
    let tup = (1, 2)
    T tup
    

    老实说,我不完全确定将元组作为参数传递给多个参数的方法的规则是什么——这有点棘手。从逻辑上讲,可以将成员视为接受元组,但由于可选参数和编译(它作为普通方法编译)的缘故,这并不是全部,因此行为有些微妙。但是定义一个显式的重载接受一个元组(它将被编译为taking System.Tuple )做这个把戏!