[swift] 스위프트 상수 : Struct 또는 Enum

둘 중 어느 것이 상수를 정의하는 것이 더 나은지 잘 모르겠습니다. 구조체 또는 열거 형. 구조체는 사용할 때마다 복사됩니까? static let상수 가있는 구조체에 대해 생각할 때 제 생각에는 항상 복사 될 것이라는 것은 의미가 없습니다. 그러나 그것이 복사되지 않으면 내가 무엇을 가져가는 것이 중요하지 않습니까?

구조체 또는 열거 형을 선택하면 어떤 이점이 있습니까?

Francisco는 Struct를 사용한다고 말합니다.

Ray Wenderlich는 Enum을 사용한다고 말합니다. 그러나 나는 정당성이 부족합니다.



답변

구조체와 열거 모두 작동합니다. 예를 들어, 둘 다

struct PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

enum PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

작동하고 정적 속성을 정의합니다 PhysicalConstants.speedOfLight.

Re : 구조체는 사용할 때마다 복사됩니까?

struct및 둘 다 enum값 유형이므로 열거 형에도 적용됩니다. 하지만 여기서는 값을 전혀 만들 필요가 없기 때문에 관련 이 없습니다. 정적 속성 ( 유형 속성 이라고도 함 )은 해당 유형의 인스턴스가 아니라 유형 자체의 속성입니다.

Re : 구조체 또는 열거 형을 선택하면 어떤 이점이 있습니까?

링크 된 문서 에서 언급했듯이 :

대소 문자가없는 열거를 사용하는 이점은 실수로 인스턴스화 할 수없고 순수 네임 스페이스로 작동한다는 것입니다.

따라서 구조의 경우

let foo = PhysicalConstants()

유형의 (쓸모없는) 값을 생성 PhysicalConstants하지만 대소 문자가없는 열거의 경우 컴파일에 실패합니다.

let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers


답변

짧은 대답은 다음과 같습니다. 상수가 고유해야합니까? 그런 다음이를 적용하는 열거 형을 사용합니다.

동일한 값을 포함하기 위해 여러 다른 상수를 사용하고 싶으십니까 (종종 명확성을 위해 유용함)? 그런 다음이를 허용하는 구조체를 사용하십시오.


답변

둘 사이의 한 가지 차이점은 열거 형이 할 수없는 곳에서 구조체를 인스턴스화 할 수 있다는 것입니다. 따라서 상수 만 사용해야하는 대부분의 시나리오에서는 혼동을 피하기 위해 열거 형을 사용하는 것이 가장 좋습니다.

예를 들면 :

struct Constants {
    static let someValue = "someValue"
}

let _ = Constants()

위의 코드는 여전히 유효합니다.

열거 형을 사용하는 경우 :

enum Constants {
    static let someValue = "someValue"
}

let _ = Constants() // error

위의 코드는 유효하지 않으므로 혼동을 피하십시오.


답변

Xcode 7.3.1 및 Swift 2.2 사용

Martin R에 동의하고 Ray Wenderlich 스타일 가이드는 enum이 순수한 네임 스페이스이기 때문에 거의 모든 사용 사례에서 더 좋다는 점을 지적하지만, struct트럼프를 사용하는 곳이 한 곳 enums있습니다.

Switch 문

구조체 버전부터 시작하겠습니다.

struct StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

구조체를 사용하면 Matched StaticVars.someString.

이제 (키워드 만 변경하여 대소 문자를 구별 열거 버전을 고려할 수 struct에를 enum)

enum StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

case StaticVars.someString:줄 의 switch 문에서 컴파일 시간 오류가 발생하는 것을 알 수 있습니다. 오류는 Enum case 'someString' not found in type 'String'입니다.

정적 속성을 대신 형식을 반환하는 클로저로 변환하는 의사 해결 방법이 있습니다.

따라서 다음과 같이 변경합니다.

enum StaticVars {
    static let someString = { return "someString" }
}

switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

이제는 함수이므로 case 문에 괄호가 필요합니다.

단점은 이제 함수로 만들었으므로 호출 될 때마다 실행된다는 것입니다. 따라서 String또는 과 같은 단순한 기본 유형이라면 Int그렇게 나쁘지 않습니다. 본질적으로 계산 된 속성입니다. 계산해야하는 상수이고 한 번만 계산하려는 경우 다른 속성으로 계산하고 이미 계산 된 값을 클로저에 반환하는 것을 고려하십시오.

기본 이니셜 라이저를 개인용으로 재정의 할 수도 있습니다. 그러면 대 / 소문자가없는 열거 형과 동일한 종류의 컴파일 시간 오류를 얻을 수 있습니다.

struct StaticVars {
    static let someString = "someString"
    private init() {}
}

그러나 이것으로 구조체의 선언을 자체 파일에 넣기를 원할 것입니다. 의 인스턴스 StaticVars이지만 클래스 파일 외부에서는 의도 한대로 작동합니다. 그러나 그것은 당신의 부름입니다.


답변

에서 결합 프레임 워크, 애플은 네임 스페이스에 대한 열거 형을 선호하는 선택했다.

enum Publishers

게시자 역할을하는 유형의 네임 스페이스입니다.

enum Subscribers

구독자 역할을하는 유형의 네임 스페이스입니다.

enum Subscriptions

구독과 관련된 기호의 네임 스페이스입니다.


답변