在swift中扩展类型别名

时间:2014-10-24 12:51:07

标签: ios swift

我正在处理不同的单位,即distancealtitudespeedvolume等。

我的目标是在应用中使用优雅,独特的方式对其进行格式化,例如调用myValue.formatted

let mySpeed: Speed = 180
println(mySpeed.formatted) // 5.0 km/h

let myAltitude: Altitude = 4000
println(myAltitude.formatted) // 4000 m

我认为这是使用类型别名的好例子。

typealias Distance = Float
typealias Altitude = Float
typealias Speed = Float

对于formatted媒体资源,我尝试使用extension类型的Float

extension Float {
    var formatted: String {
        get {
            switch self {
            case is Altitude:
                return "\(self) m"
            case is Speed:
                return "\(self * 3.6) km/h"
            default:
                return "\(self)"
            }
        }
    }
}

但是编译器说我的 case块总是true

然后我尝试扩展单一类型:

extension Speed {
  var formatted: String {
    return "\(self * 3.6) km/h"
  }
}
extension Altitude {
  var formatted: String {
    return "\(self) m"
  }
}

编译器现在明确指出格式化'

的无效重新声明

好的,现在很清楚类型别名是如何工作的。但是如何在swift中为不同类型的Floats获取.formatted属性?

2 个答案:

答案 0 :(得分:6)

typealias只需更改或重命名该类型即可。它不会为您创建其他用户类型。实际上,您正在为FloatSpeed再次延长Altitude

您可以通过符合180类型将Literals传递到自定义结构。

let mySpeed: Speed = 180

FloatLiteralConvertibleIntegerLiteralConvertible将为您提供所需的相同功能,您可以在分配给struct types

时直接为自定义Float分配值
struct Speed: FloatLiteralConvertible,IntegerLiteralConvertible {

    var distance:Float
    init(floatLiteral value: Float) {
        distance = value
    }

    init(integerLiteral value: Int){
        distance = Float(value)
    }

    var formatted: String {
        return "\(distance * 3.6) km/h"
    }
}

let mySpeed: Speed = 180.0
println(mySpeed.formatted) // 5.0 km/h

答案 1 :(得分:1)

DistanceAltitudeSpeed始终属于同一类型 - Float并共享相同的formatted属性。这就是编译器查看代码的方式:

extension Float {
    var formatted: String {
        get {
            switch self {
            case is Float:
                return "\(self) m"
            case is Float:
                return "\(self * 3.6) km/h"
            default:
                return "\(self)"
            }
        }
    }
}

我想你需要为你的功能创建小包装器:

struct Distance {
    var value: Float
    var formatted: String {
        return "\(value) m"
    }

    init(_ value: Float) {
        self.value = value
    }
}

let myDistance = Distance(123)
myDistance.formatted