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#_Casting_Units Of Measurement - Fatal编程技术网

F#测量单位,在不丢失测量类型的情况下铸造

F#测量单位,在不丢失测量类型的情况下铸造,f#,casting,units-of-measurement,F#,Casting,Units Of Measurement,是否有内置版本的类型转换函数可以保留单位,若并没有,我将如何制作它们?例如,对于这段代码,我如何将intWithSecondMeasure转换为浮点,而不丢失度量值或乘以1.0 []类型s 设IntWithSecondMeasure=1 让justAFloat=以秒为单位浮动 我不认为有一种内置的方法可以做到这一点,但您可以轻松定义自己的单位保留转换函数: let float_unit (x:int<'u>) : float<'u> = unbox float x let

是否有内置版本的类型转换函数可以保留单位,若并没有,我将如何制作它们?例如,对于这段代码,我如何将intWithSecondMeasure转换为浮点,而不丢失度量值或乘以
1.0

[]类型s
设IntWithSecondMeasure=1
让justAFloat=以秒为单位浮动

我不认为有一种内置的方法可以做到这一点,但您可以轻松定义自己的单位保留转换函数:

let float_unit (x:int<'u>) : float<'u> = unbox float x
let floatWithSecondsMeasure = float_unit intWithSecondsMeasure
let float_单位(x:int=unbox float x
设floatWithSecondMeasure=float_单位intWithSecondMeasure

查看我对这个问题的回答:

这表明今天:

[<Measure>] 
type s
let intWithSecondsMeasure = 1<s>

let intUtoFloatU< [<Measure>] 'u>( x : int<'u> ) : float<'u> = //'
    let i = int x       //  drop the units
    let f = float i     //  cast
    box f :?> float<'u> //' restore the units

let floatWithS = intUtoFloatU intWithSecondsMeasure
[]
s型
设IntWithSecondMeasure=1
让intUtoFloatU<[]u>(x:int=/'
让i=int x//去掉单位
设f=float i//cast

框f:?>float由@kvb提供的答案当然有效,但我不希望使用
unbox
运算符进行此转换。我认为有一种更好的内置方式应该编译为NOP到IL(我还没有检查,但unbox很可能最终会成为IL中的
unbox
指令,从而添加运行时类型检查)

在F#中进行单位转换的首选方法是
LanguagePrimitives.TypeWithMeasure
()

让内联float32toFloat(x:float32=
x |>float |>LanguagePrimitives.FloatWithMeasure

我根据kvb和Johannes的答案编译了代码

约翰尼斯的回答

let float32toFloat (x:int<'u>) : float<'u> = 
    x |> float |> LanguagePrimitives.FloatWithMeasure

.method public static float64  float32toFloat(int32 x) cil managed
{
  // Code size       3 (0x3)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  conv.r8
  IL_0002:  ret
} // end of method Program::float32toFloat
让float32toFloat(x:int=
x |>float |>LanguagePrimitives.FloatWithMeasure
.method public static float64 float32toFloat(int32 x)cil managed
{
//代码大小3(0x3)
.maxstack 8
IL_0000:ldarg.0
IL_0001:conv.r8
IL_0002:ret
}//方法结束程序::float32toFloat
kvb答案中添加了括号

let float_unit (x:int<'u>) : float<'u> = unbox (float x)

.method public static float64  float_unit(int32 x) cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  conv.r8
  IL_0002:  box        [mscorlib]System.Double
  IL_0007:  unbox.any  [mscorlib]System.Double
  IL_000c:  ret
} // end of method Program::float_unit
let float_单位(x:int=unbox(float x)
.method公共静态浮点64浮点单元(int32 x)cil管理
{
//代码大小13(0xd)
.maxstack 8
IL_0000:ldarg.0
IL_0001:conv.r8
IL_0002:box[mscorlib]System.Double
IL_0007:unbox.any[mscorlib]System.Double
IL_000c:ret
}//方法结束程序::浮点单位
kvb答案

let float_unit (x:int<'u>) : float<'u> = unbox float x

.method public static float64  float_unit(int32 x) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  newobj     instance void Program/float_unit@4::.ctor()
  IL_0005:  call       !!0 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::UnboxGeneric<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>>(object)
  IL_000a:  ldarg.0
  IL_000b:  tail.
  IL_000d:  callvirt   instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>::Invoke(!0)
  IL_0012:  ret
} // end of method Program::float_unit
let float_单位(x:int=unbox float x
.method公共静态浮点64浮点单元(int32 x)cil管理
{
//代码大小19(0x13)
.maxstack 8
IL_0000:newobj实例无效程序/浮动_unit@4:.ctor()
IL_0005:call!!0[FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::UnbxGeneric(对象)
IL_000a:ldarg.0
IL_000b:尾巴。
IL_000d:callvirt实例!1类[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0)
IL_0012:ret
}//方法结束程序::浮点单位

具有此签名的内容是否会进入库中?显然,它可以根据计划的FloatWithMeasure写入,但最好是有一个明确的单元安全的函数直接可用。此答案现在给出了一个警告。“此类型测试或向下转换将忽略度量单位“u”我将IL.Cast从int添加到float以与问题一致。
let float_unit (x:int<'u>) : float<'u> = unbox (float x)

.method public static float64  float_unit(int32 x) cil managed
{
  // Code size       13 (0xd)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  conv.r8
  IL_0002:  box        [mscorlib]System.Double
  IL_0007:  unbox.any  [mscorlib]System.Double
  IL_000c:  ret
} // end of method Program::float_unit
let float_unit (x:int<'u>) : float<'u> = unbox float x

.method public static float64  float_unit(int32 x) cil managed
{
  // Code size       19 (0x13)
  .maxstack  8
  IL_0000:  newobj     instance void Program/float_unit@4::.ctor()
  IL_0005:  call       !!0 [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/IntrinsicFunctions::UnboxGeneric<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>>(object)
  IL_000a:  ldarg.0
  IL_000b:  tail.
  IL_000d:  callvirt   instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<int32,float64>::Invoke(!0)
  IL_0012:  ret
} // end of method Program::float_unit