[swift] 신속하게 클래스에서 정적 상수를 정의하는 방법

내 기능에 이러한 정의가 있습니다.

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

    }
}

“테스트”를 두 번 입력 / 입력 할 필요가없는 방법이 있습니까? 감사.



답변

Swift에서 클래스에 대한 상수를 선언하는 좋은 관용구는 다음과 같이 MyClassConstants라는 구조체를 사용하는 것입니다.

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

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

이런 식으로 상수는 전역 적으로 떠 다니는 대신 선언 된 구조 내에서 범위가 지정됩니다.

최신 정보

정적 배열 초기화에 대한 의견에 대한 응답으로 정적 배열 상수를 추가했습니다. “Swift 프로그래밍 언어”의 배열 리터럴 을 참조하십시오 .

문자열 리터럴과 문자열 상수를 모두 사용하여 배열을 초기화 할 수 있습니다. 그러나 배열 유형이 알려져 testStrLength있으므로 배열 이니셜 라이저에서 정수 상수를 사용할 수 없습니다.


답변

@Martin의 답변에 추가 …

응용 프로그램 수준을 상수 파일로 유지하려는 사람이 있으면 유형 또는 특성에 따라 상수를 그룹화 할 수 있습니다.

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

전화 : Constants.MixpanelConstants.activeScreen

업데이트 5/5/2019 (주제에서 약간 벗어 났지만 ??‍♂️)

몇 가지 코드 지침과 개인적인 경험을 읽은 후 몇 가지 이유로 구조체가 전역 상수를 저장하는 가장 좋은 방법이 아닌 것 같습니다. 특히 위의 코드는 구조체 초기화를 방해하지 않습니다. 상용구 코드를 추가하여 달성 할 수 있지만 더 나은 접근 방식이 있습니다.

ENUMS

더 안전하고 명확한 표현을 가진 열거 형을 사용하여 동일한 결과를 얻을 수 있습니다.

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

print(Constants.MixpanelConstants.activeScreen.rawValue)


답변

내가 귀하의 질문을 올바르게 이해하면 a) 모든 인스턴스에서 오버 헤드를 복제하지 않고 b 그렇지 않으면 상수를 다시 계산해야하지 않도록 클래스 수준 상수 (정적-C ++ 용어)를 만드는 방법을 묻습니다.

모든 독자가 알고 있듯이 언어는 발전해 왔지만 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

컴파일러가 바이너리의 정적 섹션에 const 변수 당 하나의 항목 만 추가하기 때문에 정적이 엄격하게 필요한지 여부는 모르겠지만 구문과 액세스에 영향을 미칩니다. static을 사용하면 인스턴스가 없어도 참조 할 수 있습니다 MyClass.testStrLen..


답변

실제로 클래스의 정적 속성을 원하면 현재 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() {
    }
}


답변

계산 된 속성을 사용하는 것은 어떻습니까?

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

MyClass.myConstant


답변

일부는 특정 클래스 상수를 공개하고 다른 일부는 비공개를 원할 수 있습니다.

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

} 


답변

놀이터에서 시도 함


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