unit: github.com/ctessum/unit

## package unit

`import "github.com/ctessum/unit"`

Package unit provides a set of types and constants that facilitate the use of the International System of Units (SI).

Unit provides two main functionalities.

1) It provides a number of types representing either an SI base unit or a common combination of base units, named for the unit it represents (Length, Mass, Pressure, etc.). Each type has a float64 as the underlying unit, and its value represents the number of that underlying unit (Kilogram, Meter, Pascal, etc.). For example,

```height := 1.6 * unit.Meter
acc := unit.Acceleration(9.8)
```

creates a variable named 'height' with a value of 1.6 meters, and a variable named 'acc' with a value of 9.8 meters per second squared. These types can be used to add compile-time safety to code. For example,

```func UnitDensity(t unit.Temperature, pressure unit.Pressure) (unit.Density){
...
}
func main(){
t := 300 * unit.Kelvin
p := 5 * unit.Bar
rho := UnitDensity(p, t) // gives compile-time error
}
```

gives a compile-time error (temperature type does not match pressure type) while the corresponding code using float64 runs without error.

```func Float64Density(temperature, pressure float64) (float64){
...
}
func main(){
t := 300.0 // degrees kelvin
p := 50000.0 // Pascals
rho := Float64Density(p, t) // no error
}
```

Many types have constants defined representing named SI units (Meter, Kilogram, etc. ) or SI derived units (Bar, Milligram, etc.). These are all defined as multiples of the base unit, so, for example, the following are euqivalent

```l := 0.001 * unit.Meter
k := 1 * unit.Millimeter
j := unit.Length(0.001)
```

2) Unit provides the type "Unit", meant to represent a general dimensional value. unit.Unit can be used to help prevent errors of dimensionality when multiplying or dividing dimensional numbers. This package also provides the "Uniter" interface which is satisfied by any type which can be converted to a unit. New varibles of type Unit can be created with the New function and the Dimensions map. For example, the code

```acc := New(9.81, Dimensions{LengthDim:1, TimeDim: -2})
```

creates a variable "acc" which has a value of 9.81 m/s^2. Methods of unit can be used to modify this value, for example:

```acc.Mul(1.0 * unit.Kilogram).Mul(1 * unit.Meter)
```

To convert the unit back into a typed float64 value, the From methods of the dimensional types should be used. From will return an error if the dimensions do not match.

```var energy unit.Energy
err := (*energy).From(acc)
```

Domain-specific problems may need custom dimensions, and for this purpose NewDimension should be used to help avoid accidental overlap between packages. For example, results from a blood test may be measured in "White blood cells per slide". In this case, NewDimension should be used to create a 'WhiteBloodCell' dimension. NewDimension takes in a string which will be used for printing that dimension, and will return a unique dimension number. NewDimension should not be used, however, to create the unit of 'Slide', because in this case slide is just a measurement of area. Instead, a constant could be defined.

```const Slide unit.Area =  0.001875 // m^2
var WhiteBloodCellDim unit.Dimension
func init(){
WhiteBloodCellDim = unit.NewDimension("wbc")
}
type WbcPerArea float64
func (w WbcPerArea) Unit() *Unit{
return unit.New(float64(w), unit.Dimensions{WhiteBloodCellDim: 1, unit.LengthDim: -2})
}
func main(){
v := WbcPerArea(15)
fmt.Println(v.Unit()) // prints: 1.5e+01 m^-2 wbc
}
```

Please note that Unit cannot catch all errors related to dimensionality. Different physical ideas are sometimes expressed with the same dimensions and Unit is incapable of catching these mismatches. For example, energy and torque are both expressed as force times distance (Newton-meters in SI), but it is wrong to say that a torque of 10 N-m is the same as 10 J, even though the dimensions agree.

### Variables ¶

```var (
// Dimless is for dimensionless numbers.
Dimless = Dimensions{}
// Joule is a unit of energy [kg m2 s-2]
Joule = Dimensions{
MassDim:   1,
LengthDim: 2,
TimeDim:   -2,
}
// Meter is a meter.
Meter = Dimensions{
LengthDim: 1,
}
// Meter2 is a square meter
Meter2 = Dimensions{
LengthDim: 2,
}
// Meter3 is a cubic meter
Meter3 = Dimensions{
LengthDim: 3,
}
// Meter3PerSecond is a cubic meter per second.
Meter3PerSecond = Dimensions{
LengthDim: 3,
TimeDim:   -1,
}

// Kelvin is a degree kelvin [K].
Kelvin = Dimensions{
TemperatureDim: 1,
}

// KilogramPerMeter3 is density.
KilogramPerMeter3 = Dimensions{
MassDim:   1,
LengthDim: -3,
}
// Pascal is a unit of pressure [kg m-1 s-2]
Pascal = Dimensions{
MassDim:   1,
LengthDim: -1,
TimeDim:   -2,
}
// Kilogram is a kilogram.
Kilogram = Dimensions{
MassDim: 1,
}
// Watt is a unit of power [kg m2 s-3]
Watt = Dimensions{
MassDim:   1,
LengthDim: 2,
TimeDim:   -3,
}
// Herz is a unit of frequency [s-1]
Herz = Dimensions{
TimeDim: -1,
}
// Second is a second (time).
Second = Dimensions{
TimeDim: 1,
}
// MeterPerSecond is speed.
MeterPerSecond = Dimensions{
TimeDim:   -1,
LengthDim: 1,
}
// MeterPerSecond2 is acceleration.
MeterPerSecond2 = Dimensions{
TimeDim:   -2,
LengthDim: 1,
}
)```

### func DimensionsMatch¶Uses

`func DimensionsMatch(a, b *Unit) bool`

DimensionsMatch checks if the dimensions of two *Units are the same.

### type Dimension¶Uses

`type Dimension int`

Dimension is a type representing an SI base dimension or other orthogonal dimension. If a new dimension is desired for a domain-specific problem, NewDimension should be used. Integers should never be cast as type dimension

```// Good: Create a package constant with an init function
var MyDimension unit.Dimension
init(){
MyDimension = NewDimension("my")
}
main(){
var := MyDimension(28.2)
}
```
```const (

// CurrentDim is the dimmension representing current.
CurrentDim Dimension
// LengthDim is the dimension representing length.
LengthDim
// LuminousIntensityDim is the dimension representing luminous intensity
LuminousIntensityDim
// MassDim is the dimension representing mass
MassDim
// TemperatureDim is the dimension representing temperature
TemperatureDim
// TimeDim is the dimension representing time.
TimeDim
// AngleDim is the dimension representing angle.
AngleDim
)```

#### func NewDimension¶Uses

`func NewDimension(symbol string) Dimension`

NewDimension returns a new dimension variable which will have a unique representation across packages to prevent accidental overlap. The input string represents a symbol name which will be used for printing Unit types. This symbol may not overlap with any of the SI base units or other symbols of common use in SI ("kg", "J", "μ", etc.). A list of such symbols can be found at http://lamar.colostate.edu/~hillger/basic.htm or by consulting the package source. Furthermore, the provided symbol is also forbidden from overlapping with other packages calling NewDimension. NewDimension is expecting to be used only during initialization, and as such it will panic if the symbol matching an existing symbol NewDimension should only be called for unit types that are actually orthogonal to the base dimensions defined in this package. Please see the package-level documentation for further explanation. Calls to NewDimension are not thread safe.

#### func (Dimension) String¶Uses

`func (d Dimension) String() string`

### type Dimensions¶Uses

`type Dimensions map[Dimension]int`

Dimensions represent the dimensionality of the unit in powers of that dimension. If a key is not present, the power of that dimension is zero. Dimensions is used in conjuction with New.

#### func (Dimensions) Matches¶Uses

`func (d Dimensions) Matches(d2 Dimensions) bool`

Matches checks if the two sets of dimensions are the same.

#### func (Dimensions) String¶Uses

`func (d Dimensions) String() string`

### type Unit¶Uses

```type Unit struct {
// contains filtered or unexported fields
}```

Unit is a type a value with generic SI units. Most useful for translating between dimensions, for example, by multiplying an acceleration with a mass to get a force. Please see the package documentation for further explanation.

`func Add(u ...*Unit) *Unit`

Add adds the function arguments. It panics if the units of the arguments don't match. Any nil values are assumed to equal zero.

#### func Div¶Uses

`func Div(u ...*Unit) *Unit`

Div divides the function arguments with the first arguement as the numerator and the rest as the denominator, calculating the proper units for the result. Nil arguments cause a panic.

#### func Max¶Uses

`func Max(u ...*Unit) *Unit`

Max returns the maximum among function arguments. It panics if the units of the arguments don't match. Any nil values are ignored.

#### func Min¶Uses

`func Min(u ...*Unit) *Unit`

Min returns the minimum among function arguments. It panics if the units of the arguments don't match. Any nil values are ignored.

#### func Mul¶Uses

`func Mul(u ...*Unit) *Unit`

Mul multiplies the function arguments, calculating the proper units for the result. Nil arguments cause a panic.

#### func Negate¶Uses

`func Negate(u *Unit) *Unit`

Negate multiplies the value by -1, returning a copy of the input argument.

#### func New¶Uses

`func New(value float64, d Dimensions) *Unit`

New creates a new variable of type Unit which has the value specified by value and the dimensions specified by the base units struct. The value is always in SI Units.

Example: To create an acceleration of 3 m/s^2, one could do myvar := CreateUnit(3.0, &Dimensions{unit.LengthDim: 1, unit.TimeDim: -2})

#### func Sub¶Uses

`func Sub(u ...*Unit) *Unit`

Sub subtracts the second-through-last function arguments from the first function argument. It panics if the units of the arguments don't match. Nil arguments cause a panic.

#### func (*Unit) Add¶Uses

`func (u *Unit) Add(uu *Unit)`

Add adds uu to u, modifying u instead of creating a copy.

#### func (*Unit) Check¶Uses

`func (u *Unit) Check(d Dimensions) error`

Check checks whether u's dimensions match d, and returns an error if they don't.

#### func (*Unit) Clone¶Uses

`func (u *Unit) Clone() *Unit`

Clone makes a copy of a unit.

#### func (*Unit) Dimensions¶Uses

`func (u *Unit) Dimensions() Dimensions`

Dimensions returns the dimenstions associated with the unit.

#### func (*Unit) Div¶Uses

`func (u *Unit) Div(uu *Unit)`

Div divides u by uu, modifying u instead of creating a copy.

#### func (*Unit) Format¶Uses

`func (u *Unit) Format(fs fmt.State, c rune)`

Format makes Unit satisfy the fmt.Formatter interface. The unit is formatted with dimensions appended. If the power if the dimension is not zero or one, symbol^power is appended, if the power is one, just the symbol is appended and if the power is zero, nothing is appended. Dimensions are appended in order by symbol name with positive powers ahead of negative powers.

#### func (*Unit) Mul¶Uses

`func (u *Unit) Mul(uu *Unit)`

Mul multiplies u by uu, modifying u instead of creating a copy.

#### func (*Unit) Negate¶Uses

`func (u *Unit) Negate()`

Negate multiplies u by -1, modifying u instead of creating a copy.

#### func (*Unit) Sub¶Uses

`func (u *Unit) Sub(uu *Unit)`

Sub subtracts uu from u, modifying u instead of creating a copy.

#### func (*Unit) Value¶Uses

`func (u *Unit) Value() float64`

Value return the raw value of the unit as a float64. Use of this method is, in general, not recommended, though it can be useful for printing. Instead, the From type of a specific dimension should be used to guarantee dimension consistency.

PathSynopsis
autogen