Reputation: 639
Using enums for constants seems to be a simple and elegant solution. Is there a way I can achieve a nested string output using enums?
For example, consider I have the following piece of code:
enum Const {
enum Car {
static let Door = "Door"
static let Engine = "Engine"
}
}
Is there anyway that I can get "Car| Door" as an output for Const.Car.Door
? or "Car| Engine" as output for Const.Car.Engine
? and "Car" as output for Const.Car
?. I have some analytics constants defined in my current project similar to namespace pattern. It has a LOT of nested tracking events and would really help if I can achieve what I just described above.
What I require:
Const.Car
should give the output "Car"
Const.Car.Door
should give the output "Car| Door"
Const.Car.Engine
should give the output "Car| Engine"
I have no idea on how to achieve that.
This should be also be extendable,
For example,
Const.Car.Door.Handle
should give the output "Car| Door| Handle"
Const.Plane
should give the output "Plane"
Const.Plane.Flaps
should give the output "Plane| Flaps"
Upvotes: 2
Views: 801
Reputation: 1509
Cleanest way I can think of is:
struct Const
{
enum Car: String, CustomStringConvertible
{
case Door
case Engine
var description: String
{
return "Car\(self.rawValue)"
}
}
}
print("\(Const.Car.Door)") // CarDoor
print("\(Const.Car.Engine)") // CarEngine
Achieves what you need, makes it really easy to add new cases/parts without any boilerplate, and it would be simple to abstract away this functionality if you wish to support more vehicles.
Upvotes: 1
Reputation: 3281
Operator overloading may help you to achieve similar functionality. Please look at my solution, you can extend it a lot more
enum Vehicle: String {
case car = "Car"
case airplane = "Airplane"
enum CarPart: String {
case door = "Door"
case window = "Window"
}
}
func > (left: Vehicle, right: Vehicle.CarPart) -> String {
return left.rawValue + right.rawValue
}
let string = .car > .window // "CarWindow"
Upvotes: 3
Reputation: 3556
This doesn't exactly fulfil your requirements as it doesn't print "Car" when calling Const.Car
but it may be somewhere for you to start:
enum Const {
enum Car {
static let identifier = "Car"
static let Door = "\(Car.identifier)Door"
static let Engine = "\(Car.identifier)Engine"
}
}
print(Const.Car.Door) //CarDoor
print(Const.Car.Engine) //CarEngine
You can print "Car" by calling Const.Car.identifier
though.
Upvotes: 1
Reputation: 1024
I had a time ago a similar problem which I managed to solve using struct and enum. In your case it would look like this:
struct Const{
enum Car: String {
case Door = "CarDoor"
case Engine = "CarEngine"
}
}
print("\(Const.Car.Door)") //CarDoor
print("\(Const.Car.Engine)") //CarEngine
I hope it fits you well.
Upvotes: 1