2015-01-11 2 views
33

스위프트의 일부 속성에 게으른 초기화를 사용하고 싶습니다. 나의 현재 코드는 다음과 같습니다게으른 Var 대 Let

lazy var fontSize : CGFloat = { 
    if (someCase) { 
    return CGFloat(30) 
    } else { 
    return CGFloat(17) 
    } 
}() 

건은 fontSize는 설정되면이 절대 변하지 않을 것입니다. 그래서 다음과 같이하고 싶습니다.

lazy let fontSize : CGFloat = { 
    if (someCase) { 
    return CGFloat(30) 
    } else { 
    return CGFloat(17) 
    } 
}() 

어느 것이 불가능합니다.

만이 작동합니다

let fontSize : CGFloat = { 
    if (someCase) { 
    return CGFloat(30) 
    } else { 
    return CGFloat(17) 
    } 
}() 

그래서 - 나는로드 게으른하지만 절대 변하지 않을 것입니다 속성을합니다. 올바른 방법은 무엇입니까? let을 사용하고 게으른 초기화에 대해 잊어 버리시겠습니까? 또는 lazy var을 사용해야하고 속성의 일정한 특성을 잊어 버려야합니까?

+2

동의합니다. - 신속한 게으름이 필요합니다. 게으른 var 패턴의 또 다른 문제점 (값이 변하지 않을 것임)은 오브젝트를 돌연변이하는 것으로 처음으로 속성을 읽는 것 (내부적으로는 변경 - 지연 값이 저장 됨)이지만 외부 코드 외부 코드 관점에서 객체가 변경되지 않더라도 객체를 var로 선언해야합니다. –

+1

당신이 얻을 수있는'lazy'만이'var'(스위프트 2.1 현재)와 함께있는 것입니다. 플로트 할당이라면 게으름에 대해 걱정할 필요가 없습니다. 특히 액세스 할 것이라는 것을 절대적으로 알고 있다면 특히 – bshirley

답변

20

이것은 Xcode 6.3 Beta/Swift 1.2 release notes에서 최신 성경은 다음과 같습니다

는 상수에 더 이상 일반화하지 즉시 초기화를 요구 한 수 있습니다. 새로운 규칙은 let 상수가 사용 전에 초기화 된 (예 : var)이어야하며 초기화 후 만 다시 할당되거나 변경 될 수 없다는 것입니다.

는이 같은 패턴을 수 있습니다 :

이전에는 돌연변이 복용 곳이없는 경우에도, var에의 사용을 요구
let x: SomeThing 
if condition { 
    x = foo() 
} else { 
    x = bar() 
} 

use(x) 

. (16181314)

분명히 당신은이 일로 인해 좌절 한 사람이 아닙니다.

+0

@iGodric - 문서의 진술을 잘못 해석 한 것 같습니다. 내 의견을 삭제하겠습니다. – rghome

+0

이것은 어떻게 한 번만 지연로드하는 것을 금지합니까? –

16

스위프트 책 has the following note : 초기 값은 인스턴스 초기화가 완료 될 때까지 검색 할 수 없습니다 수 있기 때문에

당신은 항상 (var 키워드로) 변수로 게으른 속성을 선언해야합니다. 상수 속성은 초기화가 완료되기 전에 항상 값을 가져야하므로 지연으로 선언 될 수 없습니다.

모든 상수 저장 속성은 개체 초기화가 완료되기 전에 계산되므로 언어 ​​구현 컨텍스트에서 의미가 있습니다. let의 의미가 lazy과 함께 사용될 때 변경 될 수 있지만 아직 완료되지 않았으므로이 시점에서 var은 유일한 옵션으로 lazy과 함께 남아 있습니다.

지금까지 당신이 이동을 제시 한 두 가지 선택이, 내가 효율성을 기반으로 그들 사이에서 결정하는 것처럼 :

  • 속성 값에 액세스하는 거의 수행하지 않으며, 선행 계산하는 비싼 경우, I 값이 경우 이상 20..30 %에 액세스하거나 계산 상대적으로 저렴한 경우 var lazy
  • 을 사용, 나는 let

주를 사용한다 : 나는 더 밀어 코드를 최적화하는 것 conditi CGFloat 초기화로도 그러 :

let fontSize : CGFloat = CGFloat(someCase ? 30 : 17) 
+0

" 반환 "과"() "끝에? – YogevSitton

+0

@godmoney 예. 'if' 문이 조건식으로 대체되면, 문을 사용하는 데 필요한 많은 구문을 제거 할 수 있습니다. 물론 이니셜 라이저가 더 복잡하다면 - 루프를 사용할 때 구문으로 돌아 가야 할 것입니다. – dasblinkenlight

+0

감사합니다. – YogevSitton

6

dasblinkenlight가 지적했듯이 지연 속성은 항상 Swift에서 변수로 선언되어야합니다. 그러나 Entity가 정의 된 소스 파일 내에서만 변형 될 수 있도록 속성을 읽기 전용으로 만들 수 있습니다. 이것은 "게으른 let"을 정의 할 수있는 가장 가까운 것입니다.

private(set) lazy var fontSize: CGFloat = { 
    if someCase { 
     return 30 
    } else { 
     return 17 
    } 
}() 
+0

주변 유형의 변수를 '허용'할 수 없다는 언급이 있습니다. – Raphael