F#:转换为泛型类型

时间:2013-11-11 11:52:24

标签: generics casting f#

我对F#很新,来自C ++背景。我正在尝试编写一个简单的向量类,它可以是泛型类型(int,float等),但我遇到了默认构造函数的问题。我想将值初始化为零,但为了做到这一点,我需要以某种方式将一个具体的零转换为泛型类型,但我不知道如何做到这一点。

也许某些代码可能有所帮助。这是我到目前为止所做的:

type Vector3D<'T> (x :'T, y: 'T, z: 'T) = 
    member this.x = x
    member this.y = y
    member this.z = z

    new() = Vector3D<'T>(0,0,0) // what goes here?

我在突出显示的行上尝试了很多东西,但似乎无法使编译器感到满意。例如,我尝试Vector3D('T 0, 'T 0, 'T 0),我认为应将int零投射到'T零,但这不起作用。

我错过了一些基本的东西,还是只是一个获得正确语法的案例?

2 个答案:

答案 0 :(得分:5)

这是一个使用内置通用零函数的解决方案:

type Vector3D<'T> (x : 'T, y: 'T, z: 'T) =
    member this.x = x
    member this.y = y
    member this.z = z

let inline newVector () : Vector3D<_> =
    let zero = Core.LanguagePrimitives.GenericZero
    Vector3D(zero, zero, zero)

let v1 : Vector3D<int> = newVector ()
let v2 : Vector3D<double> = newVector ()
let v3 : Vector3D<int64> = newVector ()

答案 1 :(得分:3)

尝试使用defaultof功能:

type Vector3D<'T> (x :'T, y: 'T, z: 'T) = 
    member this.x = x
    member this.y = y
    member this.z = z

    new() = Vector3D<'T>(Unchecked.defaultof<'T>, 
                         Unchecked.defaultof<'T>, 
                         Unchecked.defaultof<'T>) 

请注意,如果'T是引用类型,则defaultof<'T>将为null。要解决此问题,您可以使用generic type constraint'T限制为值类型 - 也称为struct

type Vector3D<'T when 'T : struct> (x :'T, y: 'T, z: 'T) = 
    ...

有了这个,您仍然可以将此Vector3D<'T>intfloatdecimal以及许多其他常用类型一起使用,但它会保证xyz成员都不能为空。