我不知道是否可能,但我认为可以有办法做我想做的事。
我有以下情况:
enum ContactStatus: UInt {
case requestSent = 0, requestReceived, requestProcessing, active, removed
}
struct Contact {
var uid: String
var name: String?
var contactStatus: ContactStatus
init(uid: String, name: String? = nil, contactStatus: ContactStatus = .requestSent) {
self.uid = uid
self.name = name
self.contactStatus = contactStatus
}
}
class ContactStorage: {
private var contacts: [Contact]
init(contacts: [Contact]) {
contacts = contacts
}
func createContact(uid: String, contactStatus status: ContactStatus, name: String?) -> Contact {
var newContact = Contact(uid: uid)
newContact.contactStatus = status
newContact.name = name
newContacts.append(newContact)
return newContact
}
func updateContact(status: ContactStatus, peerUId: String) {
for (index, _) in contacts.enumerated() {
if contacts[index].uid == peerUId {
contacts[index].contactStatus = status
return
}
}
}
func updateContact(name: String, peerUId: String) {
for (index, _) in contacts.enumerated() {
if contacts[index].uid == peerUId {
contacts[index].name = name
return
}
}
}
}
正如我们所见,ContactStorage
有两个方法来更新联系人状态和姓名。
我希望使用通用数据类型或任何其他可能的方式将这两种方法合并为一种方法。
类似于:
func updateContact<T: Updateable>(peerUId: String, updatableProperty: T) {
//implementation
}
是否可以只写一个方法而不是两个?
最佳答案
你可以“有点”用闭包来做到这一点。
“XXX”和“YYY”部分是您拥有的两种方法之间唯一不同的部分:
for (index, _) in contacts.enumerated() {
if contacts[index].uid == peerUId {
contacts[index].XXX = YYY
return
}
}
因此,如果我们想将其提取为一个方法,我们需要一个闭包作为参数来提供“XXX”部分。
闭包看起来像这样:
(inout Contact, T) -> Void
对于“YYY”部分,常规参数就可以了。
因此,该方法如下所示:
func updateProperty<T>(property: (inout Contact, T) -> Void, value: T, peerUId: String) {
for (index, _) in contacts.enumerated() {
if contacts[index].uid == peerUId {
property(&contacts[index], value)
return
}
}
}
你可以这样调用它:
updateProperty(property: {$0.name = $1}, value: "Tom", peerUId: "something")
另一种方法是完全删除“YYY”,并将其集成到闭包中:
func updateProperty(property: (inout Contact) -> Void, peerUId: String) {
for (index, _) in contacts.enumerated() {
if contacts[index].uid == peerUId {
property(&contacts[index])
return
}
}
}
用法:
updateProperty(property: {$0.name = "Tom"}, peerUId: "something")
关于swift - 在 Swift 中更新不同数据类型属性的通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46159162/