Unidades de medidaUnits of Measure

Los valores de punto flotante y de entero F# con signo en pueden tener asociadas unidades de medida, que se suelen usar para indicar la longitud, el volumen, la masa, etc.Floating point and signed integer values in F# can have associated units of measure, which are typically used to indicate length, volume, mass, and so on. Mediante el uso de cantidades con unidades, se habilita el compilador para comprobar que las relaciones aritméticas tienen las unidades correctas, lo que ayuda a evitar errores de programación.By using quantities with units, you enable the compiler to verify that arithmetic relationships have the correct units, which helps prevent programming errors.

SintaxisSyntax

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

ComentariosRemarks

La sintaxis anterior define el nombre de unidad como unidad de medida.The previous syntax defines unit-name as a unit of measure. El elemento opcional se utiliza para definir una nueva medida en términos de unidades definidas previamente.The optional part is used to define a new measure in terms of previously defined units. Por ejemplo, la línea siguiente define la medida cm (centímetro).For example, the following line defines the measure cm (centimeter).

[<Measure>] type cm

En la línea siguiente se define ml la medida (milliliter) como un centímetrocm^3cúbico ().The following line defines the measure ml (milliliter) as a cubic centimeter (cm^3).

[<Measure>] type ml = cm^3

En la sintaxis anterior, Measure es una fórmula que implica unidades.In the previous syntax, measure is a formula that involves units. En las fórmulas que implican unidades, se admiten las potencias enteras (positivas y negativas), los espacios entre las * unidades indican un producto de las dos unidades / , también indica un producto de unidades e indica un cociente de unidades.In formulas that involve units, integral powers are supported (positive and negative), spaces between units indicate a product of the two units, * also indicates a product of units, and / indicates a quotient of units. En el caso de una unidad recíproca, puede usar una potencia entera negativa o una / que indique una separación entre el numerador y el denominador de una fórmula de unidad.For a reciprocal unit, you can either use a negative integer power or a / that indicates a separation between the numerator and denominator of a unit formula. Varias unidades del denominador deben ir entre paréntesis.Multiple units in the denominator should be surrounded by parentheses. Las unidades separadas por espacios después / de un se interpretan como parte del denominador, pero las unidades que siguen * a un se interpretan como parte del numerador.Units separated by spaces after a / are interpreted as being part of the denominator, but any units following a * are interpreted as being part of the numerator.

Puede usar 1 en expresiones unitarias, ya sea solo para indicar una cantidad sin dimensiones, o junto con otras unidades, como en el numerador.You can use 1 in unit expressions, either alone to indicate a dimensionless quantity, or together with other units, such as in the numerator. Por ejemplo, las unidades de una tasa se escribirían como 1/s, donde s indica segundos.For example, the units for a rate would be written as 1/s, where s indicates seconds. No se usan paréntesis en las fórmulas unitarias.Parentheses are not used in unit formulas. No se especifican constantes de conversión numéricas en las fórmulas unitarias; sin embargo, puede definir constantes de conversión con unidades por separado y usarlas en cálculos con comprobación unitaria.You do not specify numeric conversion constants in the unit formulas; however, you can define conversion constants with units separately and use them in unit-checked computations.

Las fórmulas de unidad que significan lo mismo pueden escribirse de varias formas equivalentes.Unit formulas that mean the same thing can be written in various equivalent ways. Por lo tanto, el compilador convierte las fórmulas unitarias en un formato coherente, que convierte las potencias negativas en recíprocos, agrupa las unidades en un solo numerador y un denominador, y alphabetizes las unidades en el numerador y el denominador.Therefore, the compiler converts unit formulas into a consistent form, which converts negative powers to reciprocals, groups units into a single numerator and a denominator, and alphabetizes the units in the numerator and denominator.

Por ejemplo, las fórmulas kg m s^-2 de m /s s * kg unidad y se convierten en kg m/s^2.For example, the unit formulas kg m s^-2 and m /s s * kg are both converted to kg m/s^2.

En las expresiones de punto flotante se usan unidades de medida.You use units of measure in floating point expressions. El uso de números de punto flotante junto con unidades de medida asociadas agrega otro nivel de seguridad de tipos y ayuda a evitar los errores de no coincidencia de unidad que se pueden producir en las fórmulas cuando se utilizan números de punto flotante débilmente tipados.Using floating point numbers together with associated units of measure adds another level of type safety and helps avoid the unit mismatch errors that can occur in formulas when you use weakly typed floating point numbers. Si escribe una expresión de punto flotante que utiliza unidades, las unidades de la expresión deben coincidir.If you write a floating point expression that uses units, the units in the expression must match.

Puede anotar literales con una fórmula de unidad entre corchetes angulares, tal como se muestra en los ejemplos siguientes.You can annotate literals with a unit formula in angle brackets, as shown in the following examples.

1.0<cm>
55.0<miles/hour>

No se coloca un espacio entre el número y el corchete angular; sin embargo, puede incluir un sufijo fliteral como, como en el ejemplo siguiente.You do not put a space between the number and the angle bracket; however, you can include a literal suffix such as f, as in the following example.

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

Esta anotación cambia el tipo del literal de su tipo primitivo ( floatcomo) a un tipo de dimensión, float<cm> como o, en este caso, float<miles/hour>.Such an annotation changes the type of the literal from its primitive type (such as float) to a dimensioned type, such as float<cm> or, in this case, float<miles/hour>. Una anotación de unidad de <1> indica una cantidad sin dimensiones y su tipo es equivalente al tipo primitivo sin un parámetro de unidad.A unit annotation of <1> indicates a dimensionless quantity, and its type is equivalent to the primitive type without a unit parameter.

El tipo de una unidad de medida es un tipo de punto flotante o entero con signo junto con una anotación de unidad adicional, indicado entre corchetes.The type of a unit of measure is a floating point or signed integral type together with an extra unit annotation, indicated in brackets. Por lo tanto, al escribir el tipo de una conversión g de (gramos) kg a (kilogramos), se describen los tipos de la siguiente manera.Thus, when you write the type of a conversion from g (grams) to kg (kilograms), you describe the types as follows.

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

Las unidades de medida se utilizan para la comprobación unitaria en tiempo de compilación pero no se conservan en el entorno en tiempo de ejecución.Units of measure are used for compile-time unit checking but are not persisted in the run-time environment. Por lo tanto, no afectan al rendimiento.Therefore, they do not affect performance.

Las unidades de medida se pueden aplicar a cualquier tipo, no solo a los tipos de punto flotante; sin embargo, solo los tipos de punto flotante, los tipos enteros con signo y los tipos decimales admiten cantidades dimensionales.Units of measure can be applied to any type, not just floating point types; however, only floating point types, signed integral types, and decimal types support dimensioned quantities. Por lo tanto, solo tiene sentido utilizar unidades de medida en los tipos primitivos y en los agregados que contienen estos tipos primitivos.Therefore, it only makes sense to use units of measure on the primitive types and on aggregates that contain these primitive types.

En el ejemplo siguiente se muestra el uso de unidades de medida.The following example illustrates the use of units of measure.

// 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

En el ejemplo de código siguiente se muestra cómo convertir un número de punto flotante no dimensional en un valor de punto flotante de dimensión.The following code example illustrates how to convert from a dimensionless floating point number to a dimensioned floating point value. Solo tiene que multiplicar por 1,0 y aplicar las dimensiones a 1,0.You just multiply by 1.0, applying the dimensions to the 1.0. Puede abstraerlo en una función como degreesFahrenheit.You can abstract this into a function like degreesFahrenheit.

Además, cuando pase valores con dimensiones a funciones que esperan números de punto flotante sin dimensiones, debe cancelar las unidades o convertirlos en float mediante el float operador.Also, when you pass dimensioned values to functions that expect dimensionless floating point numbers, you must cancel out the units or cast to float by using the float operator. En este ejemplo, se divide por 1.0<degC> para los argumentos en printf porque printf espera cantidades no dimensionales.In this example, you divide by 1.0<degC> for the arguments to printf because printf expects dimensionless quantities.

[<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."

En la sesión de ejemplo siguiente se muestran los resultados de las entradas y en este código.The following example session shows the outputs from and inputs to this code.

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

Uso de unidades genéricasUsing Generic Units

Puede escribir funciones genéricas que operan en datos que tienen una unidad de medida asociada.You can write generic functions that operate on data that has an associated unit of measure. Para ello, especifique un tipo junto con una unidad genérica como parámetro de tipo, tal y como se muestra en el ejemplo de código siguiente.You do this by specifying a type together with a generic unit as a type parameter, as shown in the following code example.

// 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

Crear tipos de agregado con unidades genéricasCreating Aggregate Types with Generic Units

En el código siguiente se muestra cómo crear un tipo de agregado que consta de valores de punto flotante individuales que tienen unidades que son genéricas.The following code shows how to create an aggregate type that consists of individual floating point values that have units that are generic. Esto permite crear un único tipo que funciona con una variedad de unidades.This enables a single type to be created that works with a variety of units. Además, las unidades genéricas conservan la seguridad de tipos asegurándose de que un tipo genérico que tiene un conjunto de unidades es un tipo diferente del mismo tipo genérico con un conjunto de unidades diferente.Also, generic units preserve type safety by ensuring that a generic type that has one set of units is a different type than the same generic type with a different set of units. La base de esta técnica es que el Measure atributo se puede aplicar al parámetro de tipo.The basis of this technique is that the Measure attribute can be applied to the type parameter.

 // 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> }

Unidades en tiempo de ejecuciónUnits at Runtime

Las unidades de medida se utilizan para la comprobación de tipos estáticos.Units of measure are used for static type checking. Cuando se compilan los valores de punto flotante, se eliminan las unidades de medida, por lo que las unidades se pierden en tiempo de ejecución.When floating point values are compiled, the units of measure are eliminated, so the units are lost at run time. Por lo tanto, no es posible cualquier intento de implementar la funcionalidad que depende de la comprobación de las unidades en tiempo de ejecución.Therefore, any attempt to implement functionality that depends on checking the units at run time is not possible. Por ejemplo, no es ToString posible implementar una función para imprimir las unidades.For example, implementing a ToString function to print out the units is not possible.

ConversionesConversions

Para convertir un tipo que tiene unidades (por ejemplo, float<'u>) en un tipo que no tiene unidades, puede usar la función de conversión estándar.To convert a type that has units (for example, float<'u>) to a type that does not have units, you can use the standard conversion function. Por ejemplo, puede usar float para convertir en un float valor que no tiene unidades, como se muestra en el código siguiente.For example, you can use float to convert to a float value that does not have units, as shown in the following code.

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

Para convertir un valor sin unidades en un valor que tiene unidades, puede multiplicar por un valor 1 o 1,0 anotado con las unidades adecuadas.To convert a unitless value to a value that has units, you can multiply by a 1 or 1.0 value that is annotated with the appropriate units. Sin embargo, para escribir capas de interoperabilidad, también hay algunas funciones explícitas que puede usar para convertir valores sin unidades en valores con unidades.However, for writing interoperability layers, there are also some explicit functions that you can use to convert unitless values to values with units. Se encuentran en el módulo Microsoft. FSharp. Core. LanguagePrimitives .These are in the Microsoft.FSharp.Core.LanguagePrimitives module. Por ejemplo, para convertir de una unidad float a una float<cm>, use floatwithmeasure (, tal y como se muestra en el código siguiente.For example, to convert from a unitless float to a float<cm>, use FloatWithMeasure, as shown in the following code.

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

Unidades de medida en la F# biblioteca principalUnits of Measure in the F# Core library

Una biblioteca de unidades está disponible en FSharp.Data.UnitSystems.SI el espacio de nombres.A unit library is available in the FSharp.Data.UnitSystems.SI namespace. Incluye las unidades si en su forma de símbolo (como m para el medidor) en UnitSymbols el subespacio de nombres y su nombre completo ( meter como para el medidor) UnitNames en el subespacio de nombres.It includes SI units in both their symbol form (like m for meter) in the UnitSymbols sub-namespace, and their full name (like meter for meter) in the UnitNames sub-namespace.

Vea tambiénSee also