在Swift中

时间:2016-02-09 08:06:39

标签: swift swift2

我正在实现一个转换器,可以根据提供的单位样式,公制或英制,轻松地将运行的double类型参数转换为适当的单位。以米为单位输入距离,根据给定的单位样式将其转换为km或英里。

enum用于两种单位风格状态

//enum to track the states of unit style
enum UnitStyle{
    case Metric, Imperial
}

protocol由运行的每个参数实现。这需要模型实现一个名为Unit的类型,因为每个参数都有自己的单元类型。例如对于距离,它可以超出km或mi,而对于速度,它可以超出km / hr或mi / hr

//every parameter of run has to implement this protocol
protocol RunParameter{

    typealias Unit: RawRepresentable
    var value: Double{get set}
    var unit: Unit{get}
    var unitStyle: UnitStyle{get set}
}

这个扩展做了所有的魔术。它将给定运行参数的值乘以其合适的单位以获得正确的值。一切都很好,直到这里。现在我需要在此方法中获取单元描述,以便我可以将其返回到屏幕上显示。为此,我在description中创建了一个enum Unit变量,但问题是我无法在协议扩展中访问此description变量。 简而言之,协议扩展中的rawValue没有self.unit变量只有description变量。

extension RunParameter where Unit.RawValue == Double{

mutating func getValueForUnitStyle(unitStyle: UnitStyle) -> Double{

    self.unitStyle = unitStyle
    return value * self.unit.rawValue
    //here I want to return both calculated value and unit string
    //but unable to access unit description on self.unit
   }
}

struct Distance: RunParameter {
   enum Unit: Double {

        case km = 0.001
        case m = 1.0
        case mi = 0.000621371

        var description: String{

        switch self{
        case .km: return "km"
        case .m: return "m"
        case .mi: return "mi"
        }
     }
 }

   var value: Double
   var unitStyle = UnitStyle.Metric
   var unit: Unit {

        get{

            switch unitStyle{
            case .Metric: return Unit.km
            case .Imperial: return Unit.mi
        }
    }
}

init(value: Double){

    self.value = value
   }
}

struct Run {
    var unitStyle = UnitStyle.Imperial
    var distance = Distance(value: 10.0)
}

description变量可在此处获得。我可以访问x.distance.unit

上的说明
var x = Run()
let z = x.distance.getValueForUnitStyle(.Imperial)
x.distance.unit.description //output "mi"

1 个答案:

答案 0 :(得分:1)

enum UnitStyle{
    case Metric, Imperial
}

protocol RunParameter{

    typealias Unit: RawRepresentable, CustomStringConvertible
    var value: Double{get set}
    var unit: Unit{get}
    var unitStyle: UnitStyle{get set}
}
extension RunParameter where Unit.RawValue == Double{

    mutating func getValueForUnitStyle(unitStyle: UnitStyle) -> (Double,String){

        self.unitStyle = unitStyle
        return (value * self.unit.rawValue, self.unit.description)
        //here I want to return both calculated value and unit string
        //but unable to access unit description on self.unit
    }
}

struct Distance: RunParameter {
    enum Unit: Double, CustomStringConvertible {

        case km = 0.001
        case m = 1.0
        case mi = 0.000621371

        var description: String{

            switch self{
            case .km: return "km"
            case .m: return "m"
            case .mi: return "mi"
            }
        }
    }

    var value: Double
    var unitStyle = UnitStyle.Metric
    var unit: Unit {

        get{

            switch unitStyle{
            case .Metric: return Unit.km
            case .Imperial: return Unit.mi
            }
        }
    }

    init(value: Double){

        self.value = value
    }
}

struct Run {
    var unitStyle = UnitStyle.Imperial
    var distance = Distance(value: 10.0)
}

var x = Run()
let z = x.distance.getValueForUnitStyle(.Imperial)
x.distance.unit.description //output "mi"

print(z.0,z.1) // 0.00621371 mi