2014-09-25 68 views
18

虽然玩了一点Swift,我试着编写一个只读和懒惰的初始化属性。我很快就写了这行代码来了解它是不允许的。swift中的懒惰只读属性

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

您必须将惰性属性声明为var。 雨燕书中明确指出,让懒是不可能的一个很好的理由:

“你必须声明一个懒惰的属性作为一个变量(使用var关键字),因为它的初始值可能不被检索直到实例初始化完成。恒属性必须总是有一个值初始化完成,因此不能被声明为懒惰。”

假如我想在迅速只读懒财产。什么是最好的方式来存档?

回答

33

如果只读和私人是你在同义词这种特殊情况下,那么你可以让二传手私人通过明确声明它:

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

这是不可改变和懒惰之间的良好平衡。

+0

私人二传手对我来说是足够的。我经常在C#中使用这种模式。 – MBulli 2014-09-26 13:52:13

+0

我认为这相当于private(set)lazy var foo = 42'''。如果您将setter标记为private,则仅仅为了省略setter而声明getter是没有意义的。 – 2014-12-03 10:04:51

+3

它不是一个getter,它是一个懒惰的实例化闭包,但它不是必需的,因为它不包含任何逻辑。这就是为什么'private(set)lazy var foo = 42'将以同样的方式工作的原因。 – Danchoys 2014-12-12 07:04:17

5

你也可以使用一个私人的支持变量初始化懒洋洋地:

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

虽然你的答案是正确的,我宁愿Antonios答案,因为它不会引入另一个属性。 – MBulli 2014-09-26 13:53:43

+0

虽然接受的答案目前没有工作,但确实如此。 – Barry 2015-05-24 23:41:24

+0

@Barry接受的答案现在工作(截至Xcode 7.1) – 2015-11-03 03:37:02

2

其可能与计算性能和私人结构来做到这一点。在静态var值上不需要lazy关键字,因为分配块的结果是隐含惰性的。

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

这是聪明的,在某些情况下我觉得很有用,但令人遗憾的是,当计算出的值取决于“self”对象时,它是无用的,因为swift doesn不允许内部结构关闭外部范围。 – 2017-03-08 18:20:29

+0

@丹尼尔你提出了一个很好的观点,但是这种方法在问题的背景下完美地工作。 – kevin 2017-03-09 15:17:07