Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define static constant in a generic class in swift?

So how do you define generic class constants in Swift?

The problem

For a "normal" class you can define them like this:

class C {
    static let k = 1
}

let a = C.k // 1

But if you do the same on a generic class:

class C<T> {
    static let k = 1
}

You get the following error on compilation:

Static stored properties not yet supported in generic types

So how to solve this?

My current solution

Right now, I'm using struct to solve this:

struct CConstant {
     static let K = 1
 }

This is not defined in the scope of the generic class but it works for me. Do you have a better solution?

--

ps: this is my first question here, so please help me improve this question if you think it is necessary =)

like image 782
ghashi Avatar asked Sep 17 '16 06:09

ghashi


2 Answers

For trivial value-typed constants, you could simply implement a read-only static computed property:

class C<T> {
    // will be evaluated every time the static property is accessed,
    // therefore not suited for non-trivial constants.
    static var k : Int { return 1 }
}

let a = C<()>.k // Access k on C<Void>

This has the benefit of not polluting the 'global namespace', as it's a static member on C<T>. Although unfortunately, you have to specify a generic parameter in order to use the constant – as you cannot refer to the type of a generic class without the generic parameter (as anything at the static scope may require it to be defined).

For non-trivial constants, you could define a private global constant, and use a read-only static computed property in your generic class in order to expose it to the outside world:

private let _k = SomeClass()

class C<T> {
    static var k : SomeClass { return _k }
}

Again, this allows you to access it as a static member on C<T> while not polluting the 'global namespace' (albeit not outside the Swift file you define it in).

like image 125
Hamish Avatar answered Sep 27 '22 19:09

Hamish


You can define global constant with fileprivate or private access level in the same .swift file where your generic class is defined. So it will not be visible outside of this file and will not pollute global (module) namespace.

If you need to access this constant from outside of current file then declare it as internal (default access level) or public and name it like ClassConstant so it will be obvious that it relates to Class.

Read more about access levels in Swift 3.

like image 41
mixel Avatar answered Sep 27 '22 19:09

mixel