How to define static constant in a class in swift

I have these definition in my function which work

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

But if I move 'testStr' and 'testStrLen' to the class level, it won't compile. It said 'MyClass.Type does not have a member named 'testStr'.

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


func myFunc() {


}
}

How can I fix this? I don't want to pay the penalty for counting len of a constant 'test' everytime.

Based on my understanding of the comments below, I need to do this:

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


func myFunc() {


}
}

Is there a way I don't need to type/enter "test" twice? Thanks.

144517 次浏览

If you actually want a static property of your class, that isn't currently supported in Swift. The current advice is to get around that by using global constants:

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() {
}
}

也许在 Swift 中为类声明常量的一个很好的习惯用法是像下面这样使用一个名为 MyClassConstants 的结构。

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


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

通过这种方式,常量的作用域将在已声明的构造中,而不是在全局范围内浮动。

更新

我添加了一个静态数组常量,以响应询问静态数组初始化的注释。参见“快速编程语言”中的 数组字面值

注意,字符串文字和字符串常量都可以用来初始化数组。但是,由于数组类型是已知的,因此不能在数组初始值设定项中使用整数常量 testStrLength

使用计算属性怎么样?

class MyClass {
class var myConstant: String { return "What is Love? Baby don't hurt me" }
}


MyClass.myConstant

如果我没有理解错你的问题,你是在问如何创建类级别常量(用 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,即使没有实例 MyClass.testStrLen,也可以引用它。

加上@Martin 的回答... ..。

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

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)

有些类可能希望某些类常量是公共的,而其他类可能是私有的。

private keyword can be used to limit the scope of constants within the same swift file.

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)")
}


}

在操场上试过


类 MyClass {

结构常数{ Static let testStr = “ test” Static let testStrLen = testStr.properties s.count //testInt 不能被其他类在不同的快速文件中访问 Private static let testInt = 1 函数() { //可供查阅 Print (“ Print singletonFunctiontestInt = (testInt)”) Var newInt = testStrLen newInt = newInt + 1 Print (“ Print singletonFunctiontestStr = (testStr)”) } } 函数(){ //无法访问 //var newInt1 = Constants.testInt + 1 Var newInt2 = Constants.testStrLen NewInt2 = newInt2 + 1 print("Print ownFunction testStr=\(Constants.testStr)") Print (“ Print own function newInt2 = (newInt2)”) } } 让 newInt = MyClass. Constants.testStrLen Print (“ Print testStr = (MyClass. Constants.testStr)”) Print (“ Print testInt = (newInt)”) let myClass = MyClass() Owner 函数() 函数()

testStr被评估为 之前初始化,testStrLen也是,所以除非初始化完成,否则坏的 testStr不可用。死胡同。

有两种解决方案,第一种解决方案说明只有在 self可用之后才能调用 testStrLen:

let testStr = "test"
var testStrLen: Int  {
get {
countElements(testStr)
}
}

(myClassInstance.testStrLen的用法完全相同)

the second solution is smarter:

let testStr: String // don't set here; note: the type needs to be specified
let testStrLen: Int // don't set here; note: ditto


init() {
// now we can
testStr = "test"
testStrLen = countElements(testStr)
}