Swift中struct init的编译器错误

时间:2016-10-09 17:49:54

标签: swift struct init

我有以下结构:

struct Person {
   let name: String
   let age: Int
   let assets: Double
}

要初始化一个人,我想传递一个包含姓名和年龄的字典,以及计算资产的信息:

public init(info: [String : AnyObject]) {
        if let name = info["name"] as? String {
            self.name = name
        }

        if let age = info["age"] as? Int {
            self.age = age
        }

        if let assets = info["assets"] as? [String : AnyObject] {
            calculateAssets(assets: assets)
        }
    }

    mutating func calculateAssets(assets: [String : AnyObject]) {
        self.assets = 1+2+3.4  // really do this with info from the dictionary
    }

通过此设置,我得到两个编译器错误:

  1. 在初始化所有存储属性之前使用'self'
  2. 从初始化程序返回,而不初始化所有存储的属性
  3. 根据编译器建议,我为每个属性添加了一个默认值,并将它们更改为var

    struct Person {
        var name: String = ""
        var age: Int = 0
        var assets: Double = 0.0
    
    // init ...
    }
    

    事实上,编译器错误已经消失。

    但是,通过进行这些更正,我是否在正确的轨道上?

2 个答案:

答案 0 :(得分:1)

您遇到编译器错误,因为您设置它们时变量为not inited。(您将它们定义为inited)。这就是为什么第二种情况,当你initnilerror时,optionals消失了。对于这种情况,Swift有?。可以同时为零和值。检查here。您可以添加optional,这会生成变量struct Person { var name: String? var age: Int? var assets: Double? // init ... }

        x=sc._jvm.com.abc.def.App
        x.getMessage()
        u'Hello'
        x.getMessage()
        u'Hello'

答案 1 :(得分:1)

问题是,在您的init函数中,可能初始化变量,但您无法确定,因为if语句的条件可以是{{ 1}}。这就是编译器为您提供错误的原因(也是因为当变量可能仍未初始化时,您试图在另一个函数中调用false - 因此您至少需要将此更改为{{1} })。

如果您无法确定self.assets字典中的值是否有效,则应将变量更改为var

现在你有两个选择:

  • 为您的变量提供默认值(就像您在示例中所做的那样)
  • 将变量声明为info(如@Özgür所建议的那样)。

您的选择取决于更有意义。如果您的默认值对您的情况有意义,并且您可以使用具有这些值的变量,那么我将继续使用它。

否则,您应该使用varOptionals显然有一个加号,你不需要初始化它们,但后来你需要在你想要使用它们时隐式或显式地解包它们(使用Optionals或{ {1}})。

如果 - 因任何原因 - 您可以确定Optionals字典中的值有效 - 您也可以离开?!作为常量(info)并在分配字典值时显式解包:

name

但正如我所说,只有当agelet包含有效值时才会有效,否则您将获得运行时异常。因此,“默认值”或“可选”选项是您安全和干净的选择,而这是快速而肮脏的方式。