Udostępnij za pośrednictwem


Jednostki miary (F#)

Szybująca wartości Liczba całkowita ze znakiem i pkt F# są skojarzone jednostki miary, które są zazwyczaj używane do wskazania długość, objętość, masy, i tak dalej.Przy użyciu ilości z jednostek, można włączyć kompilatora zweryfikować, że relacje arytmetyczne mają poprawne jednostek, co pomaga zapobiec błędy programowania.

[<Measure>] type unit-name [ = measure ]

Uwagi

Definiuje poprzedniego składni unit-name jako jednostkę miary.Opcjonalna część jest używany do definiowania nowej miary z wcześniej zdefiniowanych jednostek.Na przykład, poniższy wiersz definiuje środka cm (centymetr).

[<Measure>] type cm

Następujący wiersz definiuje środka ml (milliliter) jako centymetr sześcienny (cm^3).

[<Measure>] type ml = cm^3

W poprzednich składni measure jest formuła, która obejmuje jednostek.W formułach, które dotyczą jednostki, obsługiwane są integralną uprawnień (dodatnie i ujemne), spacji między jednostkami wskazują produktu dwóch jednostek, * wskazuje również produktu jednostek, i / oznacza iloraz jednostek.Dla wzajemnego jednostki, albo można użyć zasilania ujemną liczbą całkowitą lub / wskazuje, że oddzielenie Liczebnik i mianownik wzoru jednostka.Wiele jednostek w mianowniku, powinny być ujęte w nawiasy.Jednostki oddzielone spacjami po / są interpretowane jako będące częścią mianownik, ale wszelkie jednostki po * są interpretowane jako część licznika.

1 Można używać w wyrażeniach jednostki, albo samodzielnie wskazać ilość bezwymiarową, lub wraz z innych jednostek, tak jak w liczniku.Na przykład, jednostki dla stawki powinny być zapisane jako 1/s, gdzie s wskazuje sekundy.Nawiasy nie są używane w formułach jednostki.Nie określisz stałych numerycznej konwersji formuł jednostki; można jednak definiować stałe konwersji z jednostki, oddzielnie i używać ich w obliczeniach sprawdzane przez jednostkę.

Jednostki formuły, które oznaczają to samo można zapisać na różne sposoby równoważne.W związku z tym kompilator konwertuje formuły jednostki na spójne formularza, który konwertuje ujemne uprawnień odwrotności, grup jednostek pojedynczego Liczebnik i mianownik i sortuje w kolejności alfabetycznej jednostki Liczebnik i mianownik.

Na przykład formuły jednostki kg m s^-2 i m /s s * kg zarówno konwertowane na kg m/s^2.

Należy użyć jednostki miary w ruchomy punkt wyrażeń.Za pomocą liczbami wraz z jednostek miary dodaje następny poziom bezpieczeństwa typu i pomaga uniknąć błędów niezgodności jednostki, występujące w formułach, gdy używasz lekko maszynowy liczbami.Jeśli piszesz zmiennoprzecinkową punktu wyrażenie używa jednostek, jednostek w wyrażeniu muszą być zgodne.

Literały wzoru jednostka w nawiasy, można dodawać adnotacje, jak pokazano w poniższych przykładach.

1.0<cm>
55.0<miles/hour>

Nie należy umieszczać spację między liczbą i nawias kątowy; Jednakże, można użyć literału sufiks takich jak f, jak w poniższym przykładzie.

// The f indicates single-precision floating point.
55.0f<miles/hour> 

Tych adnotacji zmiany typu literał z jego typ pierwotny (takie jak float) do typu zwymiarowane, takich jak float<cm> lub, w przypadku float<miles/hour>.Adnotacja jednostki z <1> wskazuje ilość bezwymiarowy i jej typ jest równoważne typ pierwotny bez parametru jednostki.

Typ jednostki miary jest ruchomy punkt lub podpisany typem całkowitym wraz z adnotacji dodatkowe jednostki wskazane w nawiasach.W ten sposób, gdy zapis typu konwersji z g (w gramach) do kg (w kilogramach), opisują typy w następujący sposób.

let convertg2kg (x : float<g>) = x / 1000.0<g/kg>

Jednostki miary są używane do kontroli jednostkowej kompilacji, ale nie są zachowywane w środowisku run-time.W związku z tym że zagrożenie nie dotyczy wydajności.

Jednostki miary można zastosować do dowolnego typu, nie tylko przestawne typy punktów; Jednakże tylko zmiennoprzecinkowych typów, podpisane integralną typów i ilości wsparcia zwymiarowane dziesiętne typów.W związku z tym tylko warto użyć jednostki miary na typy pierwotne i zagregowanych danych, które zawierają tych typów pierwotnych.

Poniższy przykład ilustruje stosowanie jednostek miary.

// Mass, grams.
[<Measure>] type g
// Mass, kilograms.
[<Measure>] type kg
// Weight, pounds.
[<Measure>] type lb 

// Distance, meters. 
[<Measure>] type m
// Distance, cm
[<Measure>] type cm

// Distance, inches.
[<Measure>] type inch
// Distance, feet
[<Measure>] type ft

// Time, seconds.
[<Measure>] type s

// Force, Newtons.
[<Measure>] type N = kg m / s 

// Pressure, bar.
[<Measure>] type bar 
// Pressure, Pascals
[<Measure>] type Pa = N / m^2 

// Volume, milliliters.
[<Measure>] type ml 
// Volume, liters.
[<Measure>] type L

// Define conversion constants. 
let gramsPerKilogram : float<g kg^-1> = 1000.0<g/kg>
let cmPerMeter : float<cm/m> = 100.0<cm/m>
let cmPerInch : float<cm/inch> = 2.54<cm/inch>

let mlPerCubicCentimeter : float<ml/cm^3> = 1.0<ml/cm^3>
let mlPerLiter : float<ml/L> = 1000.0<ml/L>

// Define conversion functions. 
let convertGramsToKilograms (x : float<g>) = x / gramsPerKilogram
let convertCentimetersToInches (x : float<cm>) = x / cmPerInch

Poniższy przykład kodu ilustruje sposób konwertowania bezwymiarowy liczbę zmiennoprzecinkową zwymiarowany ruchomy wartość punktu.Można po prostu pomnożyć przez 1.0, stosowania wymiarów do 1.0.Można to abstrakcyjne do funkcji, takich jak degreesFahrenheit.

Również, gdy zwymiarowany wartości są przekazywane do funkcji, które oczekują, że bezwymiarowy liczbami, musisz anulować spoza jednostki lub oddane do float za pomocą float operatora.W tym przykładzie podzielić przez 1.0<degC> dla argumentów do printf ponieważ printf oczekuje, że ilości bezwymiarowe.

[<Measure>] type degC // temperature, Celsius/Centigrade
[<Measure>] type degF // temperature, Fahrenheit 

let convertCtoF ( temp : float<degC> ) = 9.0<degF> / 5.0<degC> * temp + 32.0<degF>
let convertFtoC ( temp: float<degF> ) = 5.0<degC> / 9.0<degF> * ( temp - 32.0<degF>)

// Define conversion functions from dimensionless floating point values. 
let degreesFahrenheit temp = temp * 1.0<degF>
let degreesCelsius temp = temp * 1.0<degC>

printfn "Enter a temperature in degrees Fahrenheit." 
let input = System.Console.ReadLine()
let mutable floatValue = 0.
if System.Double.TryParse(input, &floatValue)
   then 
      printfn "That temperature in Celsius is %8.2f degrees C." ((convertFtoC (degreesFahrenheit floatValue))/(1.0<degC>))
   else
      printfn "Error parsing input."

Sesja następujący przykład pokazuje wyjść i wejść do tego kodu.

Enter a temperature in degrees Fahrenheit.
90
That temperature in degrees Celsius is    32.22.

Korzystanie z jednostek rodzajowy

Można napisać ogólne funkcje, które działają na danych, które ma skojarzony jednostkę miary.Można to zrobić określając typu wraz z rodzajowego jednostki jako parametr typu, jak pokazano w poniższym przykładzie kodu.

// Distance, meters. 
[<Measure>] type m 
// Time, seconds. 
[<Measure>] type s

let genericSumUnits ( x : float<'u>) (y: float<'u>) = x + y

let v1 = 3.1<m/s>
let v2 = 2.7<m/s>
let x1 = 1.2<m>
let t1 = 1.0<s>

// OK: a function that has unit consistency checking. 
let result1 = genericSumUnits v1 v2
// Error reported: mismatched units. 
// Uncomment to see error. 
// let result2 = genericSumUnits v1 x1

Tworzenie typów agregacji z jednostkami rodzajowy

Poniższy kod ilustruje sposób tworzenia typ agregacji, która składa się z indywidualnych wartości zmiennoprzecinkowe, które mają jednostki, które są ogólne.Umożliwia to jeden typ ma zostać utworzony, który działa z różnych jednostek.Ponadto rodzajowego jednostki zachowania bezpieczeństwa typu poprzez zapewnienie, że typ rodzajowy, który ma jeden zestaw jednostek jest innego typu niż ten sam typ rodzajowy z innym zestawem jednostek.Podstawę tej techniki jest Measure atrybut mogą być stosowane do parametru typu.

// Distance, meters.
[<Measure>] type m 
// Time, seconds. 
[<Measure>] type s 

// Define a vector together with a measure type parameter. 
// Note the attribute applied to the type parameter. 
type vector3D<[<Measure>] 'u> = { x : float<'u>; y : float<'u>; z : float<'u>}

// Create instances that have two different measures. 
// Create a position vector. 
let xvec : vector3D<m> = { x = 0.0<m>; y = 0.0<m>; z = 0.0<m> }
// Create a velocity vector. 
let v1vec : vector3D<m/s> = { x = 1.0<m/s>; y = -1.0<m/s>; z = 0.0<m/s> }

Jednostki w czasie wykonywania

Jednostki miary są używane do sprawdzania typu statycznego.Gdy wartości zmiennoprzecinkowe są kompilowane, jednostki miary są wyeliminowane, więc jednostki są tracone w czasie wykonywania.W związku z tym każda próba wykonania funkcji, która zależy od sprawdzania jednostki w czasie wykonywania nie jest możliwe.Na przykład wykonawczych ToString funkcji, aby wydrukować jednostki nie jest możliwe.

Konwersje

Do konwersji typu, który ma jednostki (na przykład, float<'u>) do typu, który nie ma jednostki, można użyć funkcji konwersji standardowych.Na przykład, można użyć float do konwersji na float wartość, która nie ma jednostek, jak pokazano w poniższym kodzie.

[<Measure>]
type cm
let length = 12.0<cm>
let x = float length

Aby przekonwertować pozbawionej jednostek wartość wartość, która ma jednostki, można należy pomnożyć przez wartość 1 lub 1.0, który jest odnotowany w odpowiednich jednostkach.Do pisania warstwy interoperacyjności, istnieją jednak również niektóre funkcje jawne, które można użyć do konwersji wartości pozbawionej jednostek na wartości z jednostkami.Są one dostępne w Microsoft.FSharp.Core.LanguagePrimitives modułu.Na przykład, aby przekonwertować z pozbawionej jednostek float do float<cm>, użyj FloatWithMeasure, jak pokazano w poniższym kodzie.

open Microsoft.FSharp.Core
let height:float<cm> = LanguagePrimitives.FloatWithMeasure x

Jednostki miary w F# Power Pack

Jednostka biblioteki jest dostępna w PowerPack F#.Biblioteka jednostki obejmuje jednostek SI oraz fizyczne stałe.

Zobacz też

Inne zasoby

Materiały referencyjne dotyczące języka F#