懒惰让?结构中不合理的解决方法

时间:2017-04-02 01:59:37

标签: swift struct properties lazy-initialization let

我有一个我正在使用的不可变结构,并且我正在尝试创建计算值的属性,但是它的赋值需要先前分配的属性的值。 / p> (哇哇口)。

我正在努力的财产是perimeter: Int

// Floor made out of square tiles.
struct Floor { 

  let
  size:           (x: Int, y: Int), // How many tiles in the floor
  tilePerimeter:  Int,

  // Calculate entire floor's perimeter based on tile quantity and perimeter:
  lazy let perimeter: Int = {

    let
    t4th  = self.tilePerimeter / 4,  // Tile width / length
    sx    = self.size.x * t4th,      // All X tiles' length
    sy    = self.size.y * t4th       // All Y tiles' width

    return (sx * 2) + (sy * 2)       // Perimeter calc
  }()
};

不幸的是,Swift不允许我使用lazy let ..所以我的解决方法是只用一个getter来计算var ...但如果这个计算需要很长时间(加载一个图像或复杂的数学)然后它会被调用很多次,实际上它只需要调用一次

所以我的实际解决方法是创建一个初始化器并在那里分配周边...只有我的一些结构具有许多属性,而不是为结构创建初始化器是我喜欢的Swiftiness的一部分。

我知道我可以将它设为lazy var并将结构实例化为let,但这似乎令人困惑且容易出错。

有没有办法可以保留不变性,性能和快速性?而且,不允许使用lazy let的原因是什么?

3 个答案:

答案 0 :(得分:6)

也许你毕竟可以使用lazy var

lazy private(set) var perimeter: Int = {
    ...
}()

只读 var让您更接近所需的let语义。

答案 1 :(得分:1)

通过使用默认值为'\0'的可选私有var,您可以强制执行此计算仅一次,同时仍使用只读计算var,这与实现单例对象的方式非常相似。

nil

答案 2 :(得分:0)

使用初始化方法:

struct Floor {

    let size: (x: Int, y: Int), // How many tiles in the floor
    tilePerimeter: Int,
    perimeter: Int
  
    init(size:(x: Int, y: Int), tilePerimeter:  Int){
        self.size = size
        self.tilePerimeter = tilePerimeter
        
        // Calculate entire floor's perimeter based on tile quantity and perimeter:
        let
        t4th  = tilePerimeter / 4,  // Tile width / length
        sx    = size.x * t4th,      // All X tiles' length
        sy    = size.y * t4th       // All Y tiles' width

        self.perimeter = (sx * 2) + (sy * 2)       // Perimeter calc
    }
}