我可以在协议上使用 Swift 的 map() 吗?

Can I use Swift's map() on Protocols?

我有一些模型代码,我有一些 Thought 想要读取和写入 plist。我有以下代码:

protocol Note {
    var body: String { get }
    var author: String { get }
    var favorite: Bool { get set }
    var creationDate: Date { get }
    var id: UUID { get }
    var plistRepresentation: [String: Any] { get }
    init(plist: [String: Any])
}

struct Thought: Note {
    let body: String
    let author: String
    var favorite: Bool
    let creationDate: Date
    let id: UUID
}

extension Thought {
    var plistRepresentation: [String: Any] {
        return [
            "body": body as Any,
            "author": author as Any,
            "favorite": favorite as Any,
            "creationDate": creationDate as Any,
            "id": id.uuidString as Any
        ]
    }

    init(plist: [String: Any]) {
        body = plist["body"] as! String
        author = plist["author"] as! String
        favorite = plist["favorite"] as! Bool
        creationDate = plist["creationDate"] as! Date
        id = UUID(uuidString: plist["id"] as! String)!
    }
}

对于我的数据模型,然后在我的数据写入控制器中我有这个方法:

func fetchNotes() -> [Note] {
    guard let notePlists = NSArray(contentsOf: notesFileURL) as? [[String: Any]] else {
        return []
    }
    return notePlists.map(Note.init(plist:))
}

出于某种原因,行 return notePlists.map(Note.init(plist:)) 给出了错误 'map' produces '[T]', not the expected contextual result type '[Note]' 但是,如果我用 return notePlists.map(Thought.init(plist:)) 替换该行,我没有问题。显然我不能映射协议的初始值设定项?为什么不,还有什么替代解决方案?

如果您希望有多种符合 Note 的类型,并且想知道它存储在您的字典中的是哪种类型的笔记,您需要在您的协议中添加一个包含所有笔记类型的枚举。

enum NoteType {
    case thought 
}

将其添加到您的协议中。

protocol Note {
    var noteType: NoteType { get }
    // ...
}

并将其添加到您的笔记对象中:

 struct Thought: Note {
     let noteType: NoteType = .thought
     // ...
  }

这样您就可以从字典中读取 属性 并相应地映射它。