简体   繁体   English

F#:转换为泛型类型

[英]F#: Casting to generic type

I'm fairly new to F# and coming from a C++ background. 我是F#的新手,来自C ++背景。 I am trying to write a simple vector class which can be of generic type (int, float, etc) but I run into trouble with the default constructor. 我正在尝试编写一个简单的向量类,它可以是泛型类型(int,float等),但我遇到了默认构造函数的问题。 I want to initialize the values to be zero but to do this I need to somehow cast a concrete zero to a generic type but I'm not sure how to do this. 我想将值初始化为零,但为了做到这一点,我需要以某种方式将一个具体的零转换为泛型类型,但我不知道如何做到这一点。

Perhaps some code might help. 也许一些代码可能有所帮助 Here's what I have so far: 这是我到目前为止所拥有的:

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?

I have tried many things on the highlighted line but cannot seem to get the compiler to be happy. 我在突出显示的行上尝试了很多东西,但似乎无法让编译器感到高兴。 I tried, for instance, Vector3D('T 0, 'T 0, 'T 0) which I thought should cast the int zero to 'T zero but that did not work. 我试过,例如, Vector3D('T 0, 'T 0, 'T 0) ,我认为它应该将int零转换为'T 0但是这不起作用。

Am I missing something fundamental or is it merely a case of getting the right syntax? 我错过了一些基本的东西,还是仅仅是获得正确语法的情况?

Here's a solution which uses the built-in generic zero function: 这是一个使用内置通用零函数的解决方案:

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 ()

Try using the defaultof function: 尝试使用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>) 

Note that if 'T is a reference type, defaultof<'T> will be null. 请注意,如果'T是引用类型,则defaultof<'T>将为null。 To get around this, you can use a generic type constraint to limit 'T to value types—also known as struct 's. 为了解决这个问题,您可以使用泛型类型约束来限制'T到值类型” - 也称为struct

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

With this, you will still be able to use this Vector3D<'T> with int , float , decimal , and many other commonly used types, but it will guarantee that none of the x , y , or z , members may be null. 通过这种方式,您仍然可以将此Vector3D<'T>intfloatdecimal和许多其他常用类型一起使用,但它将保证xyz成员中的任何一个都不能为空。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM