Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 在F中没有度量值的情况下,如何创建度量记录类型#_F#_Interop_Records_Units Of Measurement - Fatal编程技术网

F# 在F中没有度量值的情况下,如何创建度量记录类型#

F# 在F中没有度量值的情况下,如何创建度量记录类型#,f#,interop,records,units-of-measurement,F#,Interop,Records,Units Of Measurement,我在公共库(LibRoot)中定义了一个记录类型,该库由C#(LibC)和F#(LibF)代码使用 然后,我在C#library(LibC)中编写了一个公共API,F#library(LibF)使用它。但每当我试图将一个对象传递给这个API时,F#都会抱怨它必须有一个度量单位 //LibRoot - F# type Vec2<[Measure] 'u> = { X : int Y : int } //LibF-F# 开放式LibC 设myVec:Vec2={X=12

我在公共库(LibRoot)中定义了一个记录类型,该库由C#(LibC)和F#(LibF)代码使用

然后,我在C#library(LibC)中编写了一个公共API,F#library(LibF)使用它。但每当我试图将一个对象传递给这个API时,F#都会抱怨它必须有一个度量单位

//LibRoot - F#
type Vec2<[Measure] 'u> = {
    X : int
    Y : int
}
//LibF-F#
开放式LibC
设myVec:Vec2={X=123;Y=456}
DoWork(myVec)//FS0001
错误FS0001:类型不匹配。预期为“Vec2”,但给定“Vec2”,元组具有 不同长度的0和1

我试过:

  • Vec2
    :FS0001
  • Vec2
    :类型中的文字无效
  • Vec2
    :类型中出现意外“')
  • Vec2
    :FS0001
  • Vec2
    :预期的度量单位,而不是类型

  • (Vec2)myVec
    :没有可用于类型“Vec2”的构造函数。如注释中所述,度量单位是在编译的.NET代码中没有表示形式的F#唯一特性,因此当您使用C#中带有单位注释的类型时,它将显示为没有单位的类型

    编译后的C#代码不会包含特殊的F#元数据,以表明这是一个单元注释类型,因此引用C#库的F#编译器不会将其识别为单元注释类型。可以说,F#编译器可以更智能地解决这个问题(因为它可以发现
    Vec2
    类型最初来自F#)

    我认为没有一种安全的方法可以将未测量的
    Vec2
    转换为测量的
    Vec2
    ,但使用
    unbox
    的不安全转换将在运行时起作用:

    let v : LibRoot.Vec2<1> = { LibRoot.Vec2.X = 1; Y = 2 }
    LibCs.Funcs.DoWork(unbox v)
    
    让v:LibRoot.Vec2={LibRoot.Vec2.X=1;Y=2}
    LibCs.Funcs.DoWork(unbox v)
    

    我认为没有一种方法可以在F#code中明确地引用类型
    Vec2
    (无量度),但是
    unbox
    可以很好地推断类型。这不是很好,所以如果您经常需要这种转换,那么最好重新设计您的库,以便C#使用不带单位的单独类型。

    Tomas的答案是正确的。我将为后代分享我的工作方法

    我的度量单位是

     [<Measure>] type Absolute
     [<Measure>] type Relative 
    
    []输入绝对值
    []类型相对
    
    我引入了可转换为
    Vec2
    进行互操作的“具体”记录类型。比如说

    type Offset2 = { 
       X : int
       Y : int 
    }
       with 
           static member ofVec (vec : Vec2<Relative>) : Offset2 = { X = vec.X; Y = vec.Y }
           static member toVec (off: Offset2) : Vec2<Relative> = { X = off.X; Y = off.Y }
    
    type Offset2={
    X:int
    Y:int
    }
    具有
    vec的静态成员(vec:Vec2):Offset2={X=vec.X;Y=vec.Y}
    静态成员toVec(off:Offset2):Vec2={X=off.X;Y=off.Y}
    

    我将它们转换为Vec2来执行数学运算,但对公共API使用“具体”类型。有额外的类型有点烦人,但它可以工作。

    可能无法完成,度量单位信息在编译后基本上会丢失。
     [<Measure>] type Absolute
     [<Measure>] type Relative 
    
    type Offset2 = { 
       X : int
       Y : int 
    }
       with 
           static member ofVec (vec : Vec2<Relative>) : Offset2 = { X = vec.X; Y = vec.Y }
           static member toVec (off: Offset2) : Vec2<Relative> = { X = off.X; Y = off.Y }