繁体   English   中英

Swift 在没有初始化程序的结构初始化时初始化属性

[英]Swift initialise property at struct initialisation without initialiser

在 swift 中,结构有一个自动生成的成员初始化器。

这意味着可以初始化以下结构,而无需我编写 init。

struct Activity  {
    
    let name: String
    let desc: String
    
    let category: Category
    let subcategory: Subcategory
    let emoji: Character
    
    let coordinate: CLLocationCoordinate2D
    
    let creationTime: Date = Date()
    let activityTime: Date
    
    let id: UUID = UUID()
    
    var comments: [Comment] = []
}

我有一个名为emoji的属性,由子类别计算。 换句话说, emoji的值取决于subcategory的值。

然而,这意味着emoji的值只能在初始化subcategory之后分配。

我应该如何在代码中做到这一点?

方法一:

提供我自己的初始化程序

init(name: String, desc: String, category: Category, subcategory: Subcategory,
     coordinate: CLLocationCoordinate2D, activityTime: Date) {
    self.name = name
    self.desc = desc
    self.category = category
    self.subcategory = subcategory
    self.coordinate = coordinate
    self.activityTime = activityTime
    self.emoji = AllCategories.categories[category]?[subcategory] ?? "❌"
}

我不喜欢这种方法,因为它添加了很多不必要的代码,只有在我添加更多属性时才会增长......我想使用生成的结构初始化程序。 另一方面,代码仍然非常简单。

方法二:

使用仅在调用时计算的lazy var

lazy var emoji: Character = {
     AllCategories.categories[category]?[subcategory] ?? "❌"
}()

我也不太喜欢这种方法,我发现它对于我想要做的事情过于复杂。 这也使emoji成为var而不是let它不是,我希望它保持不变。 另一方面,我可以继续使用自动生成的初始化程序。

问题:

  1. 我还有什么其他可能性?
  2. 如果没有,这两种方法中哪一种是最好的?

这听起来像是一个使用计算属性的好机会:

var emoji: Character {
     AllCategories.categories[category]?[subcategory] ?? "❌"
}

尽管它被声明为var ,但您实际上无法设置它。 这就是必须声明计算属性的方式。

表达式AllCategories.categories[category]?[subcategory]?? "❌" 每次使用该物业时都会评估AllCategories.categories[category]?[subcategory]?? "❌" 这不是一个太耗时的表达,所以 IMO 很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM