我有以下结构:
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
}
通过此设置,我得到两个编译器错误:
根据编译器建议,我为每个属性添加了一个默认值,并将它们更改为var
:
struct Person {
var name: String = ""
var age: Int = 0
var assets: Double = 0.0
// init ...
}
事实上,编译器错误已经消失。
但是,通过进行这些更正,我是否在正确的轨道上?
答案 0 :(得分:1)
您遇到编译器错误,因为您设置它们时变量为not inited
。(您将它们定义为inited
)。这就是为什么第二种情况,当你init
将nil
值error
时,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所建议的那样)。您的选择取决于更有意义。如果您的默认值对您的情况有意义,并且您可以使用具有这些值的变量,那么我将继续使用它。
否则,您应该使用var
。 Optionals
显然有一个加号,你不需要初始化它们,但后来你需要在你想要使用它们时隐式或显式地解包它们(使用Optionals
或{ {1}})。
如果 - 因任何原因 - 您可以确定Optionals
字典中的值有效 - 您也可以离开?
和!
作为常量(info
)并在分配字典值时显式解包:
name
但正如我所说,只有当age
和let
包含有效值时才会有效,否则您将获得运行时异常。因此,“默认值”或“可选”选项是您安全和干净的选择,而这是快速而肮脏的方式。