如何快速在类中定义静态常量


105

我在我的功能中有这些定义

class MyClass {
    func myFunc() {
        let testStr = "test"
        let testStrLen = countElements(testStr)
    }
}

但是,如果我将“ testStr”和“ testStrLen”移到类级别,它将无法编译。它说'MyClass.Type没有名为'testStr'的成员。

class MyClass {
    let testStr = "test"
    let testStrLen = countElements(testStr)

    func myFunc() {

    }
}

我怎样才能解决这个问题?我不想每次都为一个恒定的“测试”计数len付出代价。

基于对以下评论的理解,我需要这样做:

class MyClass {
    let testStr = "test"
    let testStrLen = countElements("test")

    func myFunc() {

    }
}

有没有一种方法我不需要两次输入/输入“测试”?谢谢。


3
ViewControl.Type的可能重复项没有名为的成员(属性的初始值不能取决于另一个属性。)
Martin R

1
在CGRectMake更改X和Y的可能重复(使用惰性属性的良好解决方案)
Martin R

“有没有一种方法我不需要两次输入/输入“测试”?-是的 将testStrLen的初始化移动到init方法中(如对第一个可能重复项的答案中所建议),或使用惰性初始化(如对第二个可能重复项的答案中所建议)。
Martin R

Answers:


177

在Swift中为类声明常量的一个好习惯是,仅使用名为MyClassConstants的结构,如下所示。

struct MyClassConstants{
    static let testStr = "test"
    static let testStrLength = countElements(testStr)

    static let arrayOfTests: [String] = ["foo", "bar", testStr]
}

这样,您的常量将在声明的构造中限定作用域,而不是在全局范围内浮动。

更新资料

为了响应有关静态数组初始化的评论,我添加了一个静态数组常量。请参见“ Swift编程语言”中的数组文字

请注意,字符串文字和字符串常量均可用于初始化数组。但是,由于已知数组类型,testStrLength因此不能在数组初始化程序中使用整数常量。


2
您能不能仅将常量声明为static private?他们会不再全球化吗?
sethfri 2015年

3
像使用枚举一样使用.rawValue进行拍子
DogCoffee 2015年

1
如果还要从Objective C中使用该代码,这也不是最好的解决方案,因为Swift结构不会转换为Objective C
mbpro,2015年

1
static在in Struct和in中声明常量之间有什么区别Class
Jauzee

1
@YOUNG Swift 2.2枚举可以工作,但是通常枚举具有比仅对常量进行分组更强的语义关联。在链接中,Swift枚举同时具有关联值和原始值。您可以使用原始值,但是语法是MyClassConstants.testStr.rawValue访问值,它在语法上不如just友好MyClassConstants.testStr
Martin Woolstenhulme,2016年

72

添加到@马丁的答案...

如果有人打算保留应用程序级常量文件,则可以根据其类型或性质对常量进行分组

struct Constants {
    struct MixpanelConstants {
        static let activeScreen = "Active Screen";
    }
    struct CrashlyticsConstants {
        static let userType = "User Type";
    }
}

致电: Constants.MixpanelConstants.activeScreen

更新 5/5/2019(有点题外话,但🤷🏽️)

在阅读了一些代码准则和个人经验之后,由于多种原因,似乎结构并不是存储全局常量的最佳方法。特别是上面的代码并没有阻止结构体的初始化。我们可以通过添加一些样板代码来实现,但是有更好的方法

枚举

使用具有更安全和清晰表示的枚举可以实现相同的目的

enum Constants {
    enum MixpanelConstants: String {
        case activeScreen = "Active Screen";
    }
    enum CrashlyticsConstants: String {
        case userType = "User Type";
    }
}

print(Constants.MixpanelConstants.activeScreen.rawValue)

2
谢谢。我喜欢这样,它提供了一种通过struct管理常量的优雅方法。
Abhijeet 2015年

1
通过更多示例,我在这里
Anish Parajuli웃

15

如果我正确理解了您的问题,那么您在问如何创建类级别的常量(以C ++的话来说是静态的),这样您就不会a)在每个实例中复制开销,并且b必须重新计算否则为常量的内容。

语言已经发展-每个读者都知道,但是正如我在Xcode 6.3.1中测试的那样,解决方案是:

import Swift

class MyClass {
    static let testStr = "test"
    static let testStrLen = count(testStr)

    init() {
        println("There are \(MyClass.testStrLen) characters in \(MyClass.testStr)")
    }
}

let a = MyClass()

// -> There are 4 characters in test

我不知道是否必须严格使用static,因为编译器肯定只将每个const变量仅添加一个条目到二进制的static部分中,但是它确实会影响语法和访问。通过使用静态的,你可以参考它,即使你没有一个实例:MyClass.testStrLen


11

如果您确实需要类的静态属性,则Swift目前不支持该属性。当前的建议是通过使用全局常量来解决该问题:

let testStr = "test"
let testStrLen = countElements(testStr)

class MyClass {
    func myFunc() {
    }
}

如果您希望将这些作为实例属性,则可以使用延迟存储的属性作为长度-它只会在第一次访问时进行评估,因此不会一遍又一遍地进行计算。

class MyClass {
    let testStr: String = "test"
    lazy var testStrLen: Int = countElements(self.testStr)

    func myFunc() {
    }
}

1
+1太糟糕了,似乎仍然没有比这些全局变量更好的方法。
Drux

1
我知道目前这是一种语言限制,但我宁愿不惜一切代价避免使用全局变量。我认为使用带有ClassNameConstants之类的结构容器现在是一种更好的方法。
Zorayr 2015年


7

有些人可能希望某些类常量是公共的,而另一些则希望私有。

private关键字可用于限制同一swift文件中的常量范围。

class MyClass {

struct Constants {

    static let testStr = "test"
    static let testStrLen = testStr.characters.count

    //testInt will not be accessable by other classes in different swift files
    private static let testInt = 1
}

func ownFunction()
{

    var newInt = Constants.testInt + 1

    print("Print testStr=\(Constants.testStr)")
}

}

其他类将能够访问您的类常量,如下所示

class MyClass2
{

func accessOtherConstants()
{
    print("MyClass's testStr=\(MyClass.Constants.testStr)")
}

} 

2

在操场上试过


class MyClass {

struct Constants { static let testStr = "test" static let testStrLen = testStr.characters.count //testInt will not be accessable by other classes in different swift files private static let testInt = 1 static func singletonFunction() { //accessable print("Print singletonFunction testInt=\(testInt)") var newInt = testStrLen newInt = newInt + 1 print("Print singletonFunction testStr=\(testStr)") } } func ownFunction() { //not accessable //var newInt1 = Constants.testInt + 1 var newInt2 = Constants.testStrLen newInt2 = newInt2 + 1 print("Print ownFunction testStr=\(Constants.testStr)") print("Print ownFunction newInt2=\(newInt2)") } } let newInt = MyClass.Constants.testStrLen print("Print testStr=\(MyClass.Constants.testStr)") print("Print testInt=\(newInt)") let myClass = MyClass() myClass.ownFunction() MyClass.Constants.singletonFunction()

这与问题有什么关系?
富兰克林·于
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.