class 初始化器中的可选 class 初始化器参数 Swift
Optional class initializer parameter in class initializer in Swift
我有一个名为 User 的 class init,class User 包含一些参数。现在在 Offer class 中,您可以看到我将 User class 作为参数传递,但我想将其作为可选参数。有没有办法在你的参数中有一个可选的 class ?谢谢
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)
}
}
首先这不是 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)
}
}
您的代码混淆了两个截然不同的事情:使用一组成员值初始化对象,以及从字典中提取这些成员。只需编写两个单独的初始值设定项:
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
的情况下使用 nil-coalescing 运算符 (??
) 提供 non-sensical 默认值是非常糟糕的做法。它隐藏故障并默默地引入数据完整性问题;别这样。
String
不是名为 imageURL
的成员的合适类型。使用 URL
.
- 如果这些命令来自 JSON,请使用
Codable
协议来自动化所有这些样板代码。
String
对于 ID
来说是一个糟糕的类型,主要是因为与 UUID
和 Int
等更合适的类型相比,它真的很慢。在大多数数据库中尤其如此,其中文本比较多比Int/UUID比较慢。
我有一个名为 User 的 class init,class User 包含一些参数。现在在 Offer class 中,您可以看到我将 User class 作为参数传递,但我想将其作为可选参数。有没有办法在你的参数中有一个可选的 class ?谢谢
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)
}
}
首先这不是 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)
}
}
您的代码混淆了两个截然不同的事情:使用一组成员值初始化对象,以及从字典中提取这些成员。只需编写两个单独的初始值设定项:
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
的情况下使用 nil-coalescing 运算符 (??
) 提供 non-sensical 默认值是非常糟糕的做法。它隐藏故障并默默地引入数据完整性问题;别这样。 String
不是名为imageURL
的成员的合适类型。使用URL
.- 如果这些命令来自 JSON,请使用
Codable
协议来自动化所有这些样板代码。 String
对于ID
来说是一个糟糕的类型,主要是因为与UUID
和Int
等更合适的类型相比,它真的很慢。在大多数数据库中尤其如此,其中文本比较多比Int/UUID比较慢。