둘 중 어느 것이 상수를 정의하는 것이 더 나은지 잘 모르겠습니다. 구조체 또는 열거 형. 구조체는 사용할 때마다 복사됩니까? static let상수 가있는 구조체에 대해 생각할 때 제 생각에는 항상 복사 될 것이라는 것은 의미가 없습니다. 그러나 그것이 복사되지 않으면 내가 무엇을 가져가는 것이 중요하지 않습니까?
구조체 또는 열거 형을 선택하면 어떤 이점이 있습니까?
둘 중 어느 것이 상수를 정의하는 것이 더 나은지 잘 모르겠습니다. 구조체 또는 열거 형. 구조체는 사용할 때마다 복사됩니까? static let상수 가있는 구조체에 대해 생각할 때 제 생각에는 항상 복사 될 것이라는 것은 의미가 없습니다. 그러나 그것이 복사되지 않으면 내가 무엇을 가져가는 것이 중요하지 않습니까?
구조체 또는 열거 형을 선택하면 어떤 이점이 있습니까?
답변:
구조체와 열거 모두 작동합니다. 예를 들어, 둘 다
struct PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
과
enum PhysicalConstants {
static let speedOfLight = 299_792_458
// ...
}
작동하고 정적 속성을 정의합니다 PhysicalConstants.speedOfLight.
struct및 둘 다 enum값 유형이므로 열거 형에도 적용됩니다. 하지만 여기서는 값을 전혀 만들 필요가 없기 때문에 관련 이 없습니다. 정적 속성 ( 유형 속성 이라고도 함 )은 해당 유형의 인스턴스가 아니라 유형 자체의 속성입니다.
링크 된 문서 에서 언급했듯이 :
대소 문자가없는 열거를 사용하는 이점은 실수로 인스턴스화 할 수없고 순수 네임 스페이스로 작동한다는 것입니다.
따라서 구조의 경우
let foo = PhysicalConstants()
유형의 (쓸모없는) 값을 생성 PhysicalConstants하지만 대소 문자가없는 열거의 경우 컴파일에 실패합니다.
let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers
private init() {}하면 Struct실수로 즉석에서 인스턴스화 할 수 없다는 "장점"도 유지됩니다. (물론이 "장점"는의 확장에 초기화를 포함하여 몇 가지 DEV-사용자에 의해 피할 수 Struct:하지만 경우에 우리가 어떤 이유로 거라고는 사용을 선호 Struct라기보다는 "순수 네임 스페이스"방식으로 enum다음, 개인 이니셜 라이저는 인스턴스로 사용하지 않는 좋은 보호 장치가 될 수 있습니다).
struct Constants static let speedOfLight = 300vs 비교를 위해 여기에 왔습니다 enum Constants enum Light : Int case speed = 300. 당신의 대답에서도 비교할 수 있습니까? 아니면 그 비교에 대한 또 다른 답이 있습니까?
둘 사이의 한 가지 차이점은 열거 형이 할 수없는 곳에서 구조체를 인스턴스화 할 수 있다는 것입니다. 따라서 상수 만 사용해야하는 대부분의 시나리오에서는 혼동을 피하기 위해 열거 형을 사용하는 것이 가장 좋습니다.
예를 들면 :
struct Constants {
static let someValue = "someValue"
}
let _ = Constants()
위의 코드는 여전히 유효합니다.
열거 형을 사용하는 경우 :
enum Constants {
static let someValue = "someValue"
}
let _ = Constants() // error
위의 코드는 유효하지 않으므로 혼동을 피하십시오.
Martin R에 동의하고 Ray Wenderlich 스타일 가이드는 enum이 순수한 네임 스페이스이기 때문에 거의 모든 사용 사례에서 더 좋다는 점을 지적하지만, struct트럼프를 사용하는 곳이 한 곳 enums있습니다.
구조체 버전부터 시작하겠습니다.
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이지만 클래스 파일 외부에서는 의도 한대로 작동합니다. 그러나 그것은 당신의 부름입니다.