我正在处理不同的单位,即距离,高度,速度,音量等.
我的目标是在应用程序中使用一种优雅,独特的方式来格式化它们,例如调用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
对于格式化的属性,我尝试使用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块总是正确的.
然后我试图扩展单一类型:
extension Speed {
var formatted: String {
return "\(self * 3.6) km/h"
}
}
extension Altitude {
var formatted: String {
return "\(self) m"
}
}
编译器现在明确说明’格式化’的重新声明无效
好的,现在很清楚类型别名是如何工作的.但是如何在swift中为不同类型的Floats获取我的.formatted属性?
解决方法
typealias只是更改或重命名类型.它不会为您创建其他用户类型.你实际上是再次扩展Float for Speed,Altitude.
您可以通过符合Literals类型将180传递给您的自定义结构.
let mySpeed: Speed = 180
FloatLiteralConvertible和IntegerLiteralConvertible将为您提供所需的相同功能,您可以在分配给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