问题
I would like to define a Measure type
[<Measure>] type kB
that converts to the number of bytes when explicitly cast to an int:
(int)7<kB> // would result 1024kB - explicit would be fine
Since there is no way to add an explicit conversion operator to a type like in C#, I am stuck. Anyone has an idea? Even better would be an implicit conversion, so that when a function requires numbers of bytes, it can be called like
Allocate(7<kB>) // implicit would be superfine
Special conversion functions do not appeal - writing a kB function is trivial but not as nice:
let kB(n) = 1024 * n
kB(7)
7 |> kB
A conversion function that does the same with units is not cool either
7<kB> |> convertToByte
回答1:
Are active patterns "cool" enough for you?
[<Measure>] type kB
// single case active pattern to convert from kB to raw B value
let (|Bytes|) (x : int<kB>) = int(x * 1024)
// use pattern matching in the declaration
// val printBytes : int<kB> -> unit
let printBytes (Bytes(b)) =
printfn "It's %d bytes" b
printBytes 7<kB>
// "It's 7168 bytes"
回答2:
The short answer to your question seems to be no. Which strikes me as add because this conversion is a bit shift. Alas, how about static methods as prescribed from "Programming f# 3.0" page 108?
[<Measure>]
type B =
static member toKB (x: int<B>) =
1<KB> * x / 1024<B>
and [<Measure>] KB =
static member toB (x: int<KB>) =
x * 1024<B> / 1<KB>
let b1 = 1024<B>
let kb1 = B.toKB b1
来源:https://stackoverflow.com/questions/32169761/is-it-possible-to-define-units-of-measure-for-kb-gb-with-explicit-or-impli