Ölçü Birimleri
F# içinde kayan nokta ve imzalı tamsayı değerleri, genellikle uzunluğu, birimi, kütleyi ve diğer değerleri belirtmek için kullanılan ilişkili ölçü birimlerine sahip olabilir. Miktarları birimlerle birlikte kullanarak, derleyicinin aritmetik ilişkilerin doğru birimlere sahip olduğunu doğrulamasını sağlar ve bu da programlama hatalarını önlemeye yardımcı olur.
Syntax
[<Measure>] type unit-name [ = measure ]
Açıklamalar
Önceki söz dizimi birim adını ölçü birimi olarak tanımlar. İsteğe bağlı bölümü, önceden tanımlanmış birimler bakımından yeni bir ölçü tanımlamak için kullanılır. Örneğin, aşağıdaki satır ölçü cm (centimeter) tanımlar.
[<Measure>] type cm
Aşağıdaki satırda ölçü ml (mililiter) kübik bir centimeter ( ) olarak cm^3 tanımlanmaktadır.
[<Measure>] type ml = cm^3
Önceki söz dizimsinde ölçü, birimleri içeren bir formüldür. Birimler içeren formüllerde integral güçler de (pozitif ve negatif), birimler arasındaki boşluklar iki birimin bir ürününü gösterir, aynı zamanda birimlerin bir ürününü ve birimlerin bir * / parçasını gösterir. Karşılıklı bir birim için negatif tamsayı gücü veya birim formülünü payda ile payda arasında ayrımı gösteren bir / kullanabilirsiniz. Paydada birden çok birim parantez içinde yer alacı içindedir. bir sonrasında boşlukla ayrılan birimler paydanın parçası olarak yorumlanır, ancak sonrasındaki tüm birimler paydanın parçası / * olarak yorumlanır.
Boyutsuz bir miktarı belirtmek için tek başına birim ifadelerinde 1 kullanabilir veya sayı gibi diğer birimlerle birlikte kullanabilirsiniz. Örneğin, bir oranın birimleri olarak yazılır ve 1/s burada s saniyeler gösterir. Parantezler birim formüllerde kullanılamaz. Birim formüllerde sayısal dönüştürme sabitleri belirtmezseniz; ancak, dönüştürme sabitlerini ayrı ayrı birimlerle tanımlayabilir ve bunları birim işaretli hesaplamalarda kullanabilirsiniz.
Aynı anlama gelen birim formülleri çeşitli eşdeğer yollarla yazabilirsiniz. Bu nedenle, derleyici birim formüllerini tutarlı bir biçime dönüştürür. Bu biçim negatif gücü karşılıklı olarak dönüştürür, birimleri tek bir paydaya ve paydaya dönüştürür ve birimleri paydada ve paydada alfabetik olarak alfabetik olarak gruplar.
Örneğin, ve birim kg m s^-2 formülleri m /s s * kg her ikisi de olarak kg m/s^2 dönüştürülür.
Kayan nokta ifadelerinde ölçü birimlerini kullanırsiniz. Kayan nokta sayıların ilişkili ölçü birimleriyle birlikte kullanımı, başka bir tür güvenliği düzeyi daha ekler ve zayıf yazı tipinde kayan nokta sayıları kullanırken formüllerde meydana gelen birim eşleşmesi hatalarını önlemeye yardımcı olur. Birimleri kullanan bir kayan nokta ifadesi yazarsanız ifadede yer alan birimler eşleşmeli.
Aşağıdaki örneklerde gösterildiği gibi, köşeli ayraç içinde birim formülüyle sabitlere not ebilirsiniz.
1.0<cm>
55.0<miles/hour>
Sayı ile açılı ayraç arasına boşluk koymaz; ancak, aşağıdaki örnekte olduğu gibi bir sabit f son eki dahil edin.
// The f indicates single-precision floating point.
55.0f<miles/hour>
Böyle bir ek açıklama, değişmez değerin türünü ilkel türünden (örneğin ) veya gibi bir boyuta sahip float float<cm> türe float<miles/hour> değiştirir. birim ek açıklaması boyutsuz bir miktarı gösterir ve türü, birim parametresi olmadan <1> ilkel türe eşdeğerdir.
Ölçü biriminin türü, köşeli ayraç içinde gösterilen ek bir birim ek açıklamasıyla birlikte kayan nokta veya imzalı tam tamsayı t t.dır. Bu nedenle, dönüştürme türünü g (grams) ile kg (kgs) yazarak türleri aşağıdaki gibi tanımlarsanız.
let convertg2kg (x : float<g>) = x / 1000.0<g/kg>
Ölçü birimleri derleme zamanı birim denetimi için kullanılır, ancak çalışma zamanı ortamında kalıcı olmaz. Bu nedenle, bunlar performansı etkilemez.
Ölçü birimleri yalnızca kayan nokta türlerine değil her türe uygulanabilir; ancak, yalnızca kayan nokta türleri, imzalı tam sayı türleri ve ondalık türler boyutlu miktarları destekler. Bu nedenle, ölçü birimlerini yalnızca ilkel türlerde ve bu ilkel türleri içeren toplamlarda kullanmak mantıklıdır.
Aşağıdaki örnek, ölçü birimlerinin kullanımını gösterir.
// 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^2
// 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
Aşağıdaki kod örneği, boyutsuz bir kayan nokta sayısından boyuta sahip bir kayan nokta değerine nasıl dönüştürüleceklerini göstermektedir. Yalnızca 1,0 ile çarparak boyutları 1.0'a uygular. Bunu gibi bir işlevde degreesFahrenheit özetlersiniz.
Ayrıca boyutsuz kayan nokta sayıları beklenilen işlevlere boyuta sahip değerler iletirken, işleci kullanarak birimleri iptal etmeniz veya için'e float geçmeniz float gerekir. Bu örnekte, boyutsuz 1.0<degC> miktarlar beklediğinizden, bağımsız printf değişkenleri için printf değerine bölersiniz.
[<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 parsedOk, floatValue = System.Double.TryParse(input)
if parsedOk
then
printfn "That temperature in Celsius is %8.2f degrees C." ((convertFtoC (degreesFahrenheit floatValue))/(1.0<degC>))
else
printfn "Error parsing input."
Aşağıdaki örnek oturumda, ve çıkışları bu koda girişler gösterir.
Enter a temperature in degrees Fahrenheit.
90
That temperature in degrees Celsius is 32.22.
Ölçü Birimlerini Destekleyen Temel Türler
Aşağıdaki türler veya tür kısaltma diğer adları ölçü birimi ek açıklamalarını destekler:
| F# diğer adı | CLR Türü |
|---|---|
float32/single |
System.Single |
float/double |
System.Double |
decimal |
System.Decimal |
sbyte/int8 |
System.SByte |
int16 |
System.Int16 |
int/int32 |
System.Int32 |
int64 |
System.Int64 |
byte/uint8 |
System.Byte |
uint16 |
System.UInt16 |
uint/uint32 |
System.UInt32 |
uint64 |
System.UIn64 |
nativeint |
System.IntPtr |
unativeint |
System.UIntPtr |
Örneğin, imzasız bir tamsayıya aşağıdaki gibi açıklama sızabilirsiniz:
[<Measure>]
type days
let better_age = 3u<days>
Bu özellik için imzasız tamsayı türlerinin ek olarak F# RFC FS-1091 içinde belgelenmiş.
Önceden Tanımlanmış Ölçü Birimleri
Ad alanı içinde bir birim kitaplığı FSharp.Data.UnitSystems.SI mevcuttur. Alt ad alanı içinde si birimlerini hem sembol biçimlerinde (ölçüm için) hem de alt ad alanı içinde tam m UnitSymbols adlarında (ölçüm için olduğu meter UnitNames gibi) içerir.
Genel Birimleri Kullanma
İlişkili ölçü birimine sahip veriler üzerinde çalışan genel işlevler yazabilirsiniz. Bunu, aşağıdaki kod örneğinde gösterildiği gibi tür parametresi olarak genel bir birim ile birlikte belirterek yapabilirsiniz.
// 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
Genel Birimlerle Koleksiyon Türleri Oluşturma
Aşağıdaki kod, genel birimlere sahip tek tek kayan nokta değerlerinden oluşan bir toplama türünün nasıl oluşturularak ilgili bilgileri gösterir. Bu, çeşitli birimlerle çalışan tek bir türün oluşturularak sağlar. Ayrıca, genel birimler, bir birim kümesine sahip genel bir türün farklı bir birim kümesine sahip aynı genel türden farklı bir tür olmasını sağlayarak tür güvenliğini korur. Bu tekniğin temeli, Measure özniteliğin tür parametresine uygulana bir özellik olmasıdır.
// 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> }
Çalışma Zamanında Birimler
Ölçü birimleri statik tür denetimi için kullanılır. Kayan nokta değerleri derlendiklerinden ölçü birimleri ortadan kaldırılmış olur ve bu nedenle birimler çalışma zamanında kaybolur. Bu nedenle, çalışma zamanında birimleri denetlemeye bağlı olan herhangi bir işlev uygulama girişimi mümkün değildir. Örneğin, birimleri yazdırmak ToString için bir işlev uygulamak mümkün değildir.
Dönüşümler
Birimleri olan bir türü (örneğin, ) birimleri olmayan bir türe dönüştürmek için float<'u> standart dönüştürme işlevini kullanabilirsiniz. Örneğin, aşağıdaki kodda gösterildiği gibi, birimine sahip bir değere float float dönüştürmek için kullanabilirsiniz.
[<Measure>]
type cm
let length = 12.0<cm>
let x = float length
Birimsiz bir değeri birimleri olan bir değere dönüştürmek için, uygun birimlerle açıklama ek açıklamalı 1 veya 1,0 değeriyle çarpabilir. Ancak, birlikte çalışabilirlik katmanları yazmak için, birimsiz değerleri birimleri olan değerlere dönüştürmek için kullanabileceğiniz bazı açık işlevler de vardır. Bunlar FSharp.Core.LanguagePrimitives modülündedir. Örneğin, bir birimsiz dönüştürmek için aşağıdaki kodda gösterildiği gibi float float<cm> FloatWithMeasurekullanın.
open Microsoft.FSharp.Core
let height:float<cm> = LanguagePrimitives.FloatWithMeasure x