Enum связанное значение сбивает с толку - PullRequest
0 голосов
/ 09 ноября 2018

Когда я пытаюсь использовать func obj func, я получаю сообщение об ошибке:

Невозможно вызвать 'obj' со списком аргументов типа '(message: (QueueAddable))'

Я запутался в типах 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()

1 Ответ

0 голосов
/ 12 ноября 2018

Я думаю, проблема в том, что функция ожидает тип, а не протокол. Если вы сделаете enum универсальным, используя тип, который реализует протокол, он будет работать.

Измените перечисление первые две строки следующим образом:

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()

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...