수색…


비고

런타임시 단위

측정 단위는 컴파일러의 정적 검사에만 사용되며 런타임에는 사용할 수 없습니다. 리플렉션이나 ToString 과 같은 메서드에서는 사용할 수 없습니다.

예를 들어, C #은 F # 라이브러리에 의해 정의되고 노출 된 float<m> 유형의 필드에 대해 단위가없는 double 을 제공합니다.

계산에서 일관된 단위 보장

측정 단위는 부동 유형 또는 정수에 추가 할 수있는 추가 유형 주석입니다. 컴파일 시간에 계산이 단위를 일관되게 사용하는지 확인하는 데 사용할 수 있습니다.

주석을 정의하려면 다음을 수행하십시오.

[<Measure>] type m // meters
[<Measure>] type s // seconds
[<Measure>] type accel = m/s^2 // acceleration defined as meters per second squared

일단 정의되면 주석을 사용하여 표현식이 예상되는 유형이되는지 검증 할 수 있습니다.

// Compile-time checking that this function will return meters, since (m/s^2) * (s^2) -> m
// Therefore we know units were used properly in the calculation.
let freeFallDistance (time:float<s>) : float<m> = 
    0.5 * 9.8<accel> * (time*time)    

// It is also made explicit at the call site, so we know that the parameter passed should be in seconds
let dist:float<m> = freeFallDistance 3.0<s>
printfn "%f" dist

단위 간의 전환

[<Measure>] type m // meters
[<Measure>] type cm // centimeters

// Conversion factor
let cmInM = 100<cm/m>

let distanceInM = 1<m>
let distanceInCM = distanceInM * cmInM // 100<cm>

// Conversion function
let cmToM (x : int<cm>) = x / 100<cm/m>
let mToCm (x : int<m>) = x * 100<cm/m>

cmToM 100<cm> // 1<m>
mToCm 1<m> // 100<cm>

F # 컴파일러는 1<m>100<cm> 이라는 것을 알지 못합니다. 그것이 신경 쓰는 한, 단위는 분리 된 유형이다. 미터에서 킬로그램으로 변환하는 유사한 함수를 작성할 수 있으며 컴파일러는 상관하지 않습니다.

[<Measure>] type kg

// Valid code, invalid physics
let kgToM x = x / 100<kg/m>

측정 단위를 다음과 같은 다른 단위의 배수로 정의하는 것은 불가능합니다.

// Invalid code
[<Measure>] type m = 100<cm>

그러나 "무언가"단위를 정의하기 위해 주파수를 측정하는 Hertz는 단순히 "초당"이며 매우 간단합니다.

// Valid code
[<Measure>] type s
[<Measure>] type Hz = /s

1 / 1<s> = 1 <Hz> // Evaluates to true

[<Measure>] type N = kg m/s // Newtons, measuring force. Note lack of multiplication sign.

// Usage
let mass = 1<kg>
let distance = 1<m>
let time = 1<s>

let force = mass * distance / time // Evaluates to 1<kg m/s>
force = 1<N> // Evaluates to true

LanguagePrimitives를 사용하여 단위 보존 또는 설정

함수가 저수준 연산으로 인해 유닛을 자동으로 보존하지 못하면 LanguagePrimitives 모듈을 사용하여 해당 유닛을 지원하는 프리미티브에 유닛을 설정할 수 있습니다.

/// This cast preserves units, while changing the underlying type
let inline castDoubleToSingle (x : float<'u>) : float32<'u> =
    LanguagePrimitives.Float32WithMeasure (float32 x)

측정 단위를 배정도 부동 소수점 값에 할당하려면 올바른 단위로 하나씩 곱하면됩니다.

[<Measure>]
type USD

let toMoneyImprecise (amount : float) =
   amount * 1.<USD>

측정 단위를 System.Double이 아닌 단위가없는 값으로 지정하려면 (예 : 다른 언어로 작성된 라이브러리에서 도착한 경우) 변환을 사용하십시오.

open LanguagePrimitives

let toMoney amount =
   amount |> DecimalWithMeasure<'u>

다음은 F # interactive에 의해보고 된 함수 유형입니다.

val toMoney : amount:decimal -> decimal<'u>
val toMoneyImprecise : amount:float -> float<USD>

단위 측정 유형 매개 변수

[<Measure>] 속성은 유형 매개 변수에 사용되어 측정 단위와 관련하여 일반적인 유형을 선언 할 수 있습니다.

type CylinderSize<[<Measure>] 'u> =
    { Radius : float<'u>
      Height : float<'u> }

테스트 사용 :

open Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols

/// This has type CylinderSize<m>.
let testCylinder =
    { Radius = 14.<m>
      Height =  1.<m> }

표준화 된 유닛 유형을 사용하여 호환성 유지

예를 들어 SI 단위의 형식은 F # 핵심 라이브러리 인 Microsoft.FSharp.Data.UnitSystems.SI 에서 표준화되었습니다. 적절한 하위 네임 스페이스 인 UnitNames 또는 UnitSymbols 사용합니다. 또는 SI 단위가 필요한 경우 유형 별칭을 사용하여 가져올 수 있습니다.

/// Seconds, the SI unit of time. Type abbreviation for the Microsoft standardized type.
type [<Measure>] s = Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols.s

일부 사용자는 다음을 수행하는 경향이 있습니다. 정의가 이미 사용 가능할 때마다 수행해서는 안됩니다 .

/// Seconds, the SI unit of time
type [<Measure>] s // DO NOT DO THIS! THIS IS AN EXAMPLE TO EXPLAIN A PROBLEM.

차이점은 표준 SI 유형을 참조하는 다른 코드와 인터페이스 할 때 분명 해집니다. 표준 단위를 참조하는 코드는 호환 가능하지만 자체 형식을 정의하는 코드는 특정 정의를 사용하지 않는 코드와 호환되지 않습니다.

따라서 SI 단위에는 항상 표준 형식을 사용하십시오. UnitNames 또는 UnitSymbols 를 참조하는지 여부는 관계가 없습니다 UnitNamesUnitSymbols 는 둘 중 동일한 이름이 같은 유형을 참조하기 때문입니다.

open Microsoft.FSharp.Data.UnitSystems.SI

/// This is valid, since both versions refer to the same authoritative type.
let validSubtraction = 1.<UnitSymbols.s> - 0.5<UnitNames.second>


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow