// SI units
enum Magnitude : Measurement {
case Milli = Measurement(-3, "ml")
case Centi = Measurement(-2, "cl")
case Desi = Measurement(-1, "dl")
case Gram = Measurement(0, "g")
case Kilo = Measurement(3,"kg")
}
class Measurement {
let magnitude : Int
let shorthandName : String
init(magnitude: Int, shorthandName: String) {
self.magnitude = magnitude
self.shorthandName = shorthandName
}
}
我正在将转换器作为应用程序的一部分来实现。我开始在不同质量的大小之间进行转换。我认为将Magnitude作为枚举很好,与其简短的名字紧密相关。但是Swift并没有让我有一个包含对象的枚举,因为原始值需要是一个字面值。任何人都知道一种更聪明的方式来表示幅度,速记名称和单位之间的转换之间的联系吗?
答案 0 :(得分:6)
根据您的需要,您可以组合使用SI单位比例的枚举和Apple Swift编程指南的“计算属性”部分中的示例。在这种简单的方案中,所有输入测量值都将存储在相同的单位中(本例中为克)。然后你将转换为输出中所需的任何单位。
它非常易读。
enum SI {
case kg
case hg
case dag
case g
case dg
case cg
case mg
var scale: Double {
switch self {
case kg: return 0.001
case hg: return 0.01
case dag: return 0.1
case g: return 1.0
case dg: return 10.0
case cg: return 100.0
case mg: return 1000.0
}
}
}
extension Double {
var kg: Double {return self * 1000.0}
var hg: Double {return self * 100.0}
var dag: Double {return self * 10.0}
var g: Double {return self}
var dg: Double {return self * 0.1}
var cg: Double {return self * 0.01}
var mg: Double {return self * 0.001}
func convertTo(si: SI) -> Double {return self * si.scale}
}
示例:
答案 1 :(得分:4)
如果您希望能够使用String
指定质量单位,您可以使用String
来表示简写名称和变量,以便为您提供有关该单位的更多信息,例如magnitude
。这是一个例子:
<强> 1。 MassUnit
强>
enum MassUnit: String {
case Milligrams = "mg"
case Grams = "g"
case Kilos = "kg"
case Tons = "t"
var magnitude: Int {
let mag: Int
switch self {
case .Milligrams: mag = -3
case .Grams : mag = 0
case .Kilos : mag = 3
case .Tons : mag = 6
}
return mag
}
static func ordersOfMagnitudeFrom(unit1: MassUnit, to unit2: MassUnit) -> Int {
return unit1.magnitude - unit2.magnitude
}
}
extension MassUnit: Printable {
var description: String {
return self.rawValue
}
}
<强> 2。然后,为了存储实际质量,您可以使用Struct
,它也可以处理转换。例如:
struct Mass {
var value : Double
var unit : MassUnit
static func convertMass(mass: Mass, toUnit unit: MassUnit) -> Mass {
let ordersOfMagnitude = MassUnit.ordersOfMagnitudeFrom(mass.unit, to: unit)
let multipler = pow(10.0, Double(ordersOfMagnitude))
return Mass(value: mass.value * multipler, unit: unit)
}
// Returns an optional Mass because we can't know for sure
// unitString will represent a MassUnit.
static func convertMass(mass: Mass, toUnit unitString: String) -> Mass? {
if let unit = MassUnit(rawValue: unitString) {
return convertMass(mass, toUnit: unit)
}
return nil
}
}
extension Mass {
init?(value: Double, _ unitString: String) {
if let unit = MassUnit(rawValue: unitString) {
self = Mass(value: value, unit: unit)
} else {
return nil
}
}
}
extension Mass : Printable {
var description: String {
return "\(value) \(unit)"
}
}
第3。然后你可以使用质量和单位:
if let mass = Mass(value: 1, "kg"),
let convertedMass = Mass.convertMass(mass, toUnit: "g") {
println("\(mass) converted to \(MassUnit.Grams) equals \(convertedMass)")
// Prints: 1.0 kg converted to g equals 1000.0 g
}
但是,如果您使用的unitString
无法转换为MassUnit
(在创建或转换时),则会返回nil
。例如:
let mass = Mass(value: 1, "NotAUnit") // nil
答案 2 :(得分:1)
你考虑过使用字典吗?例如:
let magnitudes: [String: Double] = [
"ml": -3,
"cl": -2,
"dl": -1,
"g": 0,
"kg": 3
]
// list all units:
println(", ".join(magnitudes.keys)) // kg, g, ml, cl, dl
// convert
func convert(from: String, to: String, value: Double) -> Double{
let mag1 = __exp10(magnitudes[from]!)
let mag2 = __exp10(magnitudes[to]!)
return value * mag1 / mag2
}
let result = convert("dl", "ml", 3.0)
println(result) // 300.0