Ö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

Ayrıca bkz.