2

当我尝试使用 func obj func 时,出现错误:

无法使用类型为“(消息:(QueueAddable))”的参数列表调用“obj”

我对 Swift 类型感到困惑。Obj func 用于获取解码的具体类型。

protocol QueueAddable: Encodable {
    var playlistsCollection:String? { get }
    var playlists: [String]? { get }
}

struct Playlist: QueueAddable {
    var playlistsCollection:String? {
        return "id"
    }
    var playlists: [String]? {
        return ["id", "id2"]
    }
    private enum CodingKeys:String,CodingKey {
        case playlistsCollection
        case playlists
    }

    public func encode(to encoder: Encoder) throws {
        var values = encoder.container(keyedBy: CodingKeys.self)
        try values.encode(playlistsCollection, forKey: Playlist.CodingKeys.playlistsCollection)
        try values.encode(playlists, forKey: .playlists)
    }
}

func obj<Q>(message: Q) where Q: QueueAddable {
    let encoder = JSONEncoder()
    let data = try! encoder.encode(message)
}

enum SomeEnum {
    case playlist(QueueAddable)
    func doSome() throws -> Data {
        switch self {
        case .playlist(let queueAddable):
            let encoder = JSONEncoder()

            // Error on the following line:
            obj(message: queueAddable)
            return Data()
        }
    }
}

let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()
4

1 回答 1

1

我认为问题在于该函数需要一种类型而不是协议。如果您使用实现协议的类型使枚举泛型,它将起作用。

像这样更改枚举的前两行

enum SomeEnum<Q : QueueAddable> {
case playlist(Q)

我在以下操场上进行了测试:

import Foundation

protocol QueueAddable: Encodable {
    var playlistsCollection:String? { get }
    var playlists: [String]? { get }
}

struct Playlist: QueueAddable {
    var playlistsCollection:String? {
        return "id"
    }
    var playlists: [String]? {
        return ["id", "id2"]
    }
    private enum CodingKeys:String,CodingKey {
        case playlistsCollection
        case playlists
    }

    public func encode(to encoder: Encoder) throws {
        var values = encoder.container(keyedBy: CodingKeys.self)
        try values.encode(playlistsCollection, forKey:      Playlist.CodingKeys.playlistsCollection)
        try values.encode(playlists, forKey: .playlists)
    }
}

func obj<Q>(message: Q) where Q: QueueAddable {
    let encoder = JSONEncoder()
    let data = try! encoder.encode(message)
}

enum SomeEnum<Q : QueueAddable> {
    case playlist(Q)
    func doSome() throws -> Data {
        switch self {
        case .playlist(let queueAddable):
            let encoder = JSONEncoder()

            // No longer error on the following line:
            obj(message: queueAddable)
            return Data()
        }
    }
}

let playlist = Playlist()
let data = try SomeEnum.playlist(playlist).doSome()

希望能帮助到你!

于 2018-11-12T06:30:09.007 回答