How to define static constant in a generic class i

2019-04-25 17:30发布

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 =)

2条回答
beautiful°
2楼-- · 2019-04-25 18:13

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.

查看更多
趁早两清
3楼-- · 2019-04-25 18:15

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).

查看更多
登录 后发表回答