Reputation: 4814
I am dealing with different units, i.e. distance
, altitude
, speed
, volume
, etc.
My goal is to have an elegant, unique way to format them in the app, like for example calling myValue.formatted
:
let mySpeed: Speed = 180
println(mySpeed.formatted) // 5.0 km/h
let myAltitude: Altitude = 4000
println(myAltitude.formatted) // 4000 m
I thought this was a good case for using type aliases.
typealias Distance = Float
typealias Altitude = Float
typealias Speed = Float
For the formatted
property, I tried with an extension
of the type 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)"
}
}
}
}
But the compiler says that my case
blocks are always true
.
Then i tried to extend the single type:
extension Speed {
var formatted: String {
return "\(self * 3.6) km/h"
}
}
extension Altitude {
var formatted: String {
return "\(self) m"
}
}
the compiler now clearly states Invalid redeclaration of 'formatted'
OK, it's clear now how type aliases work. But how would I get my .formatted
property for different types of Floats in swift?
Upvotes: 8
Views: 4183
Reputation: 37189
typealias
just change or rename the type. It does not create another user type for you. You are actually extending Float
for Speed
, Altitude
again.
You can pass 180
to your custom struct by conforming Literals
types.
let mySpeed: Speed = 180
FloatLiteralConvertible
and IntegerLiteralConvertible
will give you same functionality you want and you can directly assign values to your custom struct types
as you assign to 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
Upvotes: 7
Reputation: 27345
Distance
, Altitude
, and Speed
is always the same type - Float
and share the same formatted
property. This is how compiler sees your code:
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)"
}
}
}
}
I guess you need to create small wrappers for your functionality:
struct Distance {
var value: Float
var formatted: String {
return "\(value) m"
}
init(_ value: Float) {
self.value = value
}
}
let myDistance = Distance(123)
myDistance.formatted
Upvotes: 1