繁体   English   中英

如何在Swift中表示质量的大小?

[英]How to represent magnitude for mass in Swift?

// 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并没有让我有一个包含对象的枚举,因为原始值需要是一个字面值。 任何人都知道一种更聪明的方式来表示幅度,速记名称和单位之间的转换之间的联系吗?

根据您的需要,您可以组合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}
}

例:

在此输入图像描述

如果你想成为能够与指定的大容量的单位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

你考虑过使用字典吗? 例如:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM