2016-09-17 139 views
5

那麼你如何在Swift中定義泛型類常量?如何在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:這是我在這裏的第一個問題,所以請幫助我改進這個問題,如果你認爲有必要=)

回答

2

您可以定義全局常量與fileprivateprivate訪問級別在同一個.swift文件中您的泛型類被定義。所以它在這個文件之外是不可見的,並且不會污染全局(模塊)命名空間。

如果你需要從當前文件的外部訪問這個常量,那麼聲明爲internal(默認訪問級別)或public並將其命名爲像ClassConstant所以這將是顯而易見的,它涉及到Class

查看更多about access levels in Swift 3

+0

感謝您的回答!你的建議似乎與我目前的解決方案是一致的。我只需要根據上下文來指定訪問器。 你確切地知道爲什麼'靜態存儲屬性尚未支持泛型類型? – ghashi

+0

我認爲它們還沒有被支持,因爲你不能使用泛型類型而不指定它的類型參數。如果你只想訪問靜態屬性,那麼'SomeClass .someConstant'看起來會很難看。爲了在不指定類型參數的情況下工作,需要在編譯器中實現,我認爲這不是Swift團隊的首要任務。 – mixel

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<T>靜態成員。雖然不幸的是,您必須指定一個通用參數才能使用常量 - 因爲您不能在沒有泛型參數的情況下引用泛型類的類型(因爲靜態作用域上的任何東西都可能需要定義它)。

對於非平凡的常數,你可以定義一個私人全局常量,並在您的泛型類使用只讀靜態計算的屬性,以便將其暴露於外界:

private let _k = SomeClass() 

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

同樣,這允許您在C<T>上以靜態成員身份訪問它,同時不污染「全局名稱空間」(儘管不在您定義的Swift文件之外)。