# \`static let\` in enum vs struct?

**URL:** <https://forums.swift.org/t/static-let-in-enum-vs-struct/36152>\
**Category:** Using Swift\
**Created:** [May 4, 2020, 11:16pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152 "2020-05-04T23:16:15Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![danielbyon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/danielbyon/32/21652_2.png) [@danielbyon](https://forums.swift.org/u/danielbyon)\
**Post date:** [May 4, 2020, 11:16pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/1 "2020-05-04T23:16:16Z")

</div>

I saw this in a colleague's PR recently, and was wondering if there was a practical difference between the following:

```
enum Constants {
    // no cases
    static let animationDuration: TimeInterval = 1.5
}

struct Constants {
    static let animationDuration: TimeInterval = 1.5
    private init() { }
}

```

The argument posed for using an enum with `static let`s was that the enum could never be instantiated, but I see no difference if we were to use a struct with no instance properties and a private init.

Is there a functional/language difference between these two? There is not a difference in usage at the callsite, but I was wondering if one is recommended over the other? Using an enum with no cases "feels wrong"

---

<div class="post-metadata">

**Author:** ![suyashsrijan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/suyashsrijan/32/5292_2.png) [@suyashsrijan](https://forums.swift.org/u/suyashsrijan)\
**Post date:** [May 4, 2020, 11:23pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/2 "2020-05-04T23:23:58Z")

</div>

I personally use `enum`s for namespacing. I think it’s also a little cleaner because you don’t have to maintain an empty `private init`.

Even Apple uses `enum`s for namespacing, for example in the Combine framework.

---

<div class="post-metadata">

**Author:** ![danielbyon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/danielbyon/32/21652_2.png) [@danielbyon](https://forums.swift.org/u/danielbyon)\
**Post date:** [May 4, 2020, 11:29pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/3 "2020-05-04T23:29:28Z")

</div>

Oh interesting, I see how they use it. Very cool, I think I'll start pushing this to my team, thanks!

---

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [May 5, 2020, 5:46am UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/4 "2020-05-05T05:46:31Z")

</div>

> [@danielbyon](#):
>
> Is there a functional/language difference between these two?

Yes. A `struct` with a `private init` is still constructible: in principle, you could be given one. In your example with `struct Constants`, you could write the following code:

```swift
func foo(_ c: Constants) { }

```

and the compiler would not object.

However, an `enum` with no cases is literally non-constructible: no-one can build one. The technical term is that the type is “uninhabited”: the type exists, but there are no concrete values of the type. A `struct` with no storage is not uninhabited: there is one concrete value of the type, the value with nothing in it.

This is why the caseless `enum` is preferred: it more accurately communicates that there will never be a value of this type in the program.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [May 5, 2020, 6:35am UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/5 "2020-05-05T06:35:57Z")

</div>

There was another reason to prefer enums over structs, but I can‘t really remember it. Something about `init` from `extension`, which is only possible for structs.

---

<div class="post-metadata">

**Author:** ![anon9791410](https://avatars.discourse-cdn.com/v4/letter/a/9fc348/32.png) [@anon9791410](https://forums.swift.org/u/anon9791410)\
**Post date:** [May 5, 2020, 9:39am UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/6 "2020-05-05T09:39:39Z")

</div>

If it feels wrong, it won't. It never felt wrong to me, but it didn't feel right. And then it did and stayed that way.

Also, the name of that type is wrong. Each of the static lets is a `Constant`, not a `Constants`.

---

<div class="post-metadata">

**Author:** ![DekVester](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dekvester/32/4917_2.png) [@DekVester](https://forums.swift.org/u/DekVester)\
**Post date:** [February 12, 2021, 2:06pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/7 "2021-02-12T14:06:41Z")

</div>

Maybe a bit unrelated, but there's also this pattern in a lot of Apple's frameworks, when they use a struct as a container for static let properties of itself. This to me has always been confusing as to why not just use enum cases... Feels like I'm missing something important here. An example would be Apple HealthKit framework and its HKCorrelationTypeIdentifier (and many many others).

```
struct HKCorrelationTypeIdentifier {
    static let bloodPressure: HKCorrelationTypeIdentifier
    static let food: HKCorrelationTypeIdentifier
    // etc.
}

```

---

<div class="post-metadata">

**Author:** ![Avi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/avi/32/2962_2.png) [@Avi](https://forums.swift.org/u/Avi)\
**Post date:** [February 12, 2021, 2:19pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/8 "2021-02-12T14:19:32Z")

</div>

I believe it's because, internally, the framework can actually create instances of the type to pass around. You can't do that with uninhabited enums.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [February 12, 2021, 2:41pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/9 "2021-02-12T14:41:13Z")

</div>

Relatedly, structs can have private stored properties, which isn't possible for enums.

---

<div class="post-metadata">

**Author:** ![DekVester](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dekvester/32/4917_2.png) [@DekVester](https://forums.swift.org/u/DekVester)\
**Post date:** [February 12, 2021, 5:07pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/10 "2021-02-12T17:07:06Z")

</div>

Yes but the question is why don't they use regular enum cases instead? What is the difference between the next two types, from the usage perspective:

```
struct HKCorrelationTypeIdentifier {
    static let bloodPressure: HKCorrelationTypeIdentifier
    static let food: HKCorrelationTypeIdentifier
    // etc.
}

```

and

```
enum HKCorrelationTypeIdentifier {
    case bloodPressure
    case food
    // etc.
}

```

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [February 12, 2021, 5:28pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/11 "2021-02-12T17:28:06Z")

</div>

These are imported Objective-C types, so there are various limitations in capability and design, as well as the requirement of compatibility with other Obj-C code. In this case, `HKCorrelationTypeIdentifier` is actually declared in Obj-C as `typedef NSString *HKCorrelationTypeIdentifier;` for whatever reason. In Swift this is expressed as a new `RawRepresentable` type with static members so as to hide the constants from Swift's global namespace when importing HealthKit.

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [February 12, 2021, 6:32pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/12 "2021-02-12T18:32:20Z")

</div>

The full (storage) interface of an `enum` must be as visible as the enum itself. Anyone who can see the enum type declaration can see all of the cases and all of their associated values.

With a struct, you could have some sort of private `StorageHelper` type which you don't expose outside the struct itself—this isn't possible with enums.

Mutability is also a bit of a pain with enums. You can emulate mutable stored properties by explicitly specifying a getter and setter, but it ends up being pretty verbose compared to the equivalent for a struct:

```swift
enum E {
    case c(Int)
    case d

    var val: Int? {
        get {
            switch self {
            case .c(let val):
                return val
            case .d:
                return nil
            }
        }
        set {
            if let val = newValue {
                self = .c(val)
            } else {
                self = .d
            }
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![phoneyDev](https://avatars.discourse-cdn.com/v4/letter/p/49beb7/32.png) [@phoneyDev](https://forums.swift.org/u/phoneyDev)\
**Post date:** [February 12, 2021, 11:47pm UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/13 "2021-02-12T23:47:28Z")

</div>

You might want to actually use the struct for something. The constants are in some way related to the purpose of the struct. This is similar to `Int.max`, `Double.pi` and so forth.

---

<div class="post-metadata">

**Author:** ![EricPoon2001](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ericpoon2001/32/23327_2.png) [@EricPoon2001](https://forums.swift.org/u/EricPoon2001)\
**Post date:** [May 17, 2022, 10:21am UTC](https://forums.swift.org/t/static-let-in-enum-vs-struct/36152/14 "2022-05-17T10:21:08Z")

</div>

A quick question about that `enum`. Can we provide a clear way to tell teams that what situation we should use `enum` itself, and when to use `enum with static let` to define const?

The purpose is not to write the `enum with static let` everywhere to confuse the usage of `enum` itself.
