2014-09-25 7 views
18

Играя немного с Swift, я попытался написать readonly и lazy initialized property. Я быстро написал эту строку кода, чтобы узнать, что это запрещено.Lazy readonly property in swift

// no valid Swift code. 
lazy let foo : Int = { return 42 }() 

Вы должны объявить ленивые должности как var. Стремительная книга четко говорится, что пусть с ленивым не представляется возможное по уважительной причине:

«Вы всегда должны объявить ленивое свойство как переменные (с варом ключевым словом), потому что его начальное значение не может быть восстановлено пока не завершится инициализация экземпляра. Постоянные свойства всегда должны иметь значение до того завершения инициализации, и, следовательно, не могут быть объявлены как ленивые.»

Предположив Я хотел бы иметь только для чтения ленивой недвижимости в стриже. Каков наилучший способ архивирования?

ответ

33

Если только для чтения и частные синонимы для вас в этом конкретном случае, то вы можете сделать сеттер частным, явно объявив его:

private(set) lazy var foo : Int = { return 42 }() 

Это хороший компромисс между неизменностью и лени.

+0

Частный сеттер для меня достаточно. Я часто использую этот шаблон в C#. – MBulli

+0

Я думаю, что это эквивалентно '' 'private (set) lazy var foo = 42'''. Если вы отмечаете, что сеттер является закрытым, нет смысла объявлять геттер только для того, чтобы опустить установщик. –

+3

Это не был геттер, это ленивое закрытие экземпляра, но оно не обязательно, так как оно не содержит никакой логики. Вот почему 'private (set) lazy var foo = 42' будет работать точно так же. – Danchoys

5

Вы также можете использовать частную переменную подкладочный, инициализирующий лениво:

var foo : Int { return _foo } 
private lazy var _foo :Int = { return 42 }() 
+3

Хотя ваши ответы верны, я предпочитаю, чтобы Антониос ответил, поскольку он не вводит другое свойство. – MBulli

+0

Хотя принятый ответ в настоящее время не работает, это так. – Barry

+0

@Barry принятый ответ работает сейчас (с Xcode 7.1) –

2

Его можно сделать это с помощью вычисляемого собственности и частной структуры. Нет необходимости в ленивом ключевом слове для статического значения var, поскольку присвоение ему результата блока неявно является ленивым.

var foo: Int { 
    struct Holder { 
     static var value = { return 42 }() 
    } 
    return Holder.value 
} 
+0

Это умно и полезно в некоторых случаях, я думаю, но, к сожалению, это не полезно, когда вычисленное значение зависит от объекта «self», поскольку swift doesn 't позволяет внутренним структурам закрываться по внешней области. –

+0

@ Daniel Вы делаете отличную оценку, однако этот подход отлично работает в контексте вопроса. – kevin