【问题标题】:How to define static constant in a generic class in swift?如何快速在泛型类中定义静态常量?
【发布时间】:2016-09-17 06:36:56
【问题描述】:

那么如何在 Swift 中定义泛型类常量?

问题

对于“普通”类,您可以这样定义它们:

class C {
    static let k = 1
}

let a = C.k // 1

但是如果你在泛型类上做同样的事情:

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

编译时出现以下错误:

泛型类型尚不支持静态存储属性

那么如何解决呢?

我目前的解决方案

现在,我正在使用struct 来解决这个问题:

struct CConstant {
     static let K = 1
 }

这没有在泛型类的范围内定义,但它对我有用。 您有更好的解决方案吗?

--

ps:这是我在这里的第一个问题,所以如果您认为有必要,请帮助我改进这个问题=)

【问题讨论】:

    标签: swift generics static constants


    【解决方案1】:

    对于普通的值类型常量,您可以简单地实现一个只读的静态计算属性:

    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>
    

    这样做的好处是不会污染“全局命名空间”,因为它是C&lt;T&gt; 上的静态成员。尽管不幸的是,您必须指定一个泛型参数才能使用该常量——因为没有泛型参数就无法引用泛型类的类型(因为静态范围内的任何东西都可能需要定义它)。

    对于非平凡的常量,您可以定义一个私有全局常量,并在您的泛型类中使用只读静态计算属性,以便将其公开给外部世界:

    private let _k = SomeClass()
    
    class C<T> {
        static var k : SomeClass { return _k }
    }
    

    同样,这允许您作为 C&lt;T&gt; 上的静态成员访问它,同时不会污染“全局命名空间”(尽管不在您定义它的 Swift 文件之外)。

    【讨论】:

      【解决方案2】:

      您可以在定义泛型类的同一 .swift 文件中使用 fileprivateprivate 访问级别定义全局常量。所以它在这个文件之外是不可见的,也不会污染全局(模块)命名空间。

      如果您需要从当前文件外部访问此常量,则将其声明为internal(默认访问级别)或public,并将其命名为ClassConstant,因此很明显它与Class 相关.

      阅读更多关于access levels in Swift 3的信息。

      【讨论】:

      • 感谢您的回答!您的建议似乎与我当前的解决方案方向相同。我只需要根据上下文指定访问器。你知道为什么Static stored properties not yet supported in generic types吗?
      • 我认为它们尚不受支持,因为您不能在不指定其类型参数的情况下使用泛型类型。如果您只想访问静态属性,SomeClass&lt;SomeType&gt;.someConstant 看起来会很丑。要使其在不指定类型参数的情况下工作,需要在编译器中实现这一点,我认为这不是 Swift 团队的首要任务。
      猜你喜欢
      • 2016-02-18
      • 2011-09-28
      • 2015-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      • 2016-11-17
      相关资源
      最近更新 更多