我有一个名为User的类初始化,而User类包含一些参数。现在在Offer类中,您可以看到我将User类作为参数传递,但是我希望将其作为可选参数。有没有办法在您的参数中有一个可选的类?谢谢
struct User {
let uid: String
let username: String
init(uid: String, dictionary: [String: Any]) {
self.uid = uid
self.username = dictionary["username"] as? String ?? ""
}
}
struct Offer {
let user: User
let caption: String
let imageURL: String
let creationDate: Date
init(user: User, dictionary: [String: Any]) {
self.user = user
self.caption = dictionary["caption"] as? String ?? ""
self.imageURL = dictionary["image_url"] as? String ?? ""
let secondsFrom1970 = dictionary["creation_date"] as? Double ?? 0
self.creationDate = Date(timeIntervalSince1970: secondsFrom1970)
}
}
答案 0 :(得分:1)
您的代码混淆了两个不同的事情:使用对象的一组成员值初始化对象,以及从字典中提取这些成员。只需编写两个单独的初始化器:
import Foundation
struct User {
let uid: String
let username: String
/*
// Due to the absence of an explicit initializer declaration,
// the compiler will synthesize an implicit member-wise initailizer like this:
init(uid: String, username: String) {
self.uid = uid
self.username = username
}
*/
}
extension User {
// Putting this initializer in an extension preserves he member-wise intializer
init?(fromDict dict: [String: Any]) {
guard let uid = dict["uid"] as? String,
let username = dict["username"] as? String
else { return nil }
self.init(uid: uid, username: username)
}
}
struct Offer {
let user: User
let caption: String
let imageURL: String
let creationDate: Date
/*
// Due to the absence of an explicit initializer declaration,
// the compiler will synthesize an implicit member-wise initailizer like this:
init(
user: User,
caption: String,
imageURL: String,
creationDate: Date
) {
self.user = user
self.caption = caption
self.imageURL = imageURL
self.creationDate = creationDate
}
*/
}
extension Offer {
// Putting this initializer in an extension preserves he member-wise intializer
init?(fromDict dict: [String: Any]) {
guard let user = dict["user"] as? User,
let caption = dict["caption"] as? String,
let imageURL = dict["image_url"] as? String,
let secondsFrom1970 = dict["creation_date"] as? Double
else { return nil }
self.init(
user: user,
caption: caption,
imageURL: imageURL,
creationDate: Date(timeIntervalSince1970: secondsFrom1970)
)
}
}
一些注意事项:
??
的情况下,使用nil-coalescing运算符(nil
)提供无意义的默认值确实是一种不好的做法。它隐藏了故障,并无声地引入了数据完整性问题;不要这样做。String
对于名为imageURL
的成员来说是不合适的类型。使用URL
。Codable
协议来自动化所有这些样板代码。String
对于ID
来说是一种较差的类型,主要是因为与UUID
和Int
等更合适的类型相比,它确实很慢。这在大多数数据库中尤其如此,其中文本比较比Int / UUID比较慢得多。答案 1 :(得分:0)
首先这不是class
,而是struct
,两者都不一样。
您可以轻松创建可选参数,如下所示。
您还需要将user
属性标记为可选。
struct Offer {
let user: User?
let caption: String
let imageURL: String
let creationDate: Date
init(user: User? = nil, dictionary: [String: Any]) {
self.user = user
self.caption = dictionary["caption"] as? String ?? ""
self.imageURL = dictionary["image_url"] as? String ?? ""
let secondsFrom1970 = dictionary["creation_date"] as? Double ?? 0
self.creationDate = Date(timeIntervalSince1970: secondsFrom1970)
}
}