Is There a Technical Reason to Use Swift's Caseless Enum Instead of Real Cases

Is there a technical reason to use Swift's caseless enum instead of real cases?

Enum with cases

It is better to create an enum with cases in the following scenarios:

  • It is mutually exclusive
  • Finite set of values that you know at compile time
  • You are the one defining it (If an enum is defined in a framework you wouldn't be able to extend it to add more cases)

Advantage of an enum are:

  • Since the values are a finite set, you can write exhaustive switch statements
  • cleaner code

Static values:

When a struct / class is defined in a framework and you want to extend it to add more values.

Example of where this approach is used is Notification.Name in Foundation

Note:

  • enums in swift are quite powerful
  • enums can have associated values
  • enums can have other functions. (if you are defining states like start, inProgress, finished, you could define a function called next, which could return the next state. start.next()
  • if you are in a scenario where values are not mutually exclusive, like it could a combination of values then use OptionSet instead

Conclusion

  • It all depends on your intent

  • If you know the values before hand and they will not change, then create an enum

  • If that is not possible then create static values.

  • If you are creating static values, you are compromising so you don't have to use it in an enum, you could define it as a struct so that the intent is clearer.

  • This is as of now, there is a swift proposal for extendable enums

Swift constants: Struct or Enum

Both structs and enumerations work. As an example, both

struct PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}

and

enum PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}

work and define a static property PhysicalConstants.speedOfLight.

Re: A struct will be copied every time i use it or not?

Both struct and enum are value types so that would apply to enumerations as well. But that is irrelevant here
because you don't have to create a value at all:
Static properties (also called type properties) are properties of the type itself, not of an instance of that type.

Re: What advantages has the choice of a struct or enum?

As mentioned in the linked-to article:

The advantage of using a case-less enumeration is that it can't accidentally be instantiated and works as a pure namespace.

So for a structure,

let foo = PhysicalConstants()

creates a (useless) value of type PhysicalConstants, but
for a case-less enumeration it fails to compile:

let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers

Using static let in enum instead of case

This is a quick way of creating a namespace for constants.

You can of course achieve similar effect using a struct, however running let foo = StructOnlyForStoringConstants() will not throw an error or even a warning (can be solved using private init or even logging a warning, but we quickly lose the quick in a quick way above) and hence might be confusing (some argue). Since enums without cases (or "no-case enums") cannot be instantiated, you don't have this problem.

Another reason is that putting constants in an enum might feel more natural (than say in structs), as enums are used for storing a group of related values.

Difference between static enum and static struct

The main difference is that you cannot construct an enum with no cases. Therefore if you're just looking for something to serve as a namespace for some static members, an enum is preferred as you cannot accidently create an instance.

let e = StaticEnum() // error: 'StaticEnum' cannot be constructed because it has no accessible initializers
let s = StaticStruct() // Useless, but legal

Why Swift library uses enum CommandLine instead of struct CommandLine?

Ok, based on some research, I found this:

The advantage of using a case-less enumeration is that it can't accidentally be instantiated and works as a pure namespace. (Ref: https://github.com/raywenderlich/swift-style-guide#constants)

I believe this could possibly be one of the reasons.

Is it recommended to store constant String in extension String

No, this is really not recommended. Even though the type of the values you are storing is string, those values have no logical connection to the String class, so adding them as a type property is a bad idea in my opinion.

Those API endpoints are only connected to your business logic, so they should be stored in a type only related to your business logic and not in a "generic" type even if you declare them private.

It might also be a good idea to store the endpoints in an enum rather than in a struct or class.

private enum API {
static let foo = URL(string: "domain/models/foo")!
static let bar = URL(string: "domain/models/bar")!
}


Related Topics



Leave a reply



Submit