Использование Enum как часть программирования для протоколов в Swift - PullRequest
0 голосов
/ 20 сентября 2019

Я хочу иметь массив различных страниц (страницы HTML и PDF, возможно, добавлю еще позже).

Я подумал, что это хороший шанс попрактиковаться в программировании с протоколами.

Вот что я придумал:

protocol PageDataProtocol {
    var data: String? {get}
}

protocol PageTitleProtocol {
    var title: String {get}
    var pageType: Page {get}
}

struct PDFData: PageTitleProtocol {
    var title: String
    var pageType: Page
}

struct HTMLData: PageDataProtocol, PageTitleProtocol {
    var title: String
    var data: String?
    var pageType: Page
}

enum Page {
    case html
    case pdf
    case links
}


var pageArray : [PageTitleProtocol]? = []

let test = PDFData(title: "title1", pageType: .html)
pageArray?.append(test)

let testtwo = HTMLData(title: "title2", data: "hello", pageType: .pdf)
pageArray?.append(testtwo)


for page in pageArray! {
    print (page.title)
    if let pg = page as? HTMLData {
        print (pg.data)
    }

    if page.pageType == .pdf {
        print ( (page as? HTMLData)?.data )
    }
}

Все выглядит хорошо, но, как и в моих заявлениях о печати, есть очевидная проблема.

Редактировать: я не утверждаю, что кодидеальный выше.Но в ответе на вопрос ниже pageArray является необязательным, поскольку перед загрузкой из API может не быть страниц, но это отличается от отсутствия страниц, извлеченных из API.

Нет смысла хранить enum, так какВ любом случае я должен привести к правильному типу.

Идея заключается в том, чтобы я мог сохранять страницы в одном массиве, получать их по мере необходимости и затем отображать в моем контроллере представления (отформатированном моиммодель), а не рисование из 2+ массивов с различными типами в них.

Я представлял себе написание красивого оператора case, чтобы иметь возможность правильно отображать информацию (в моих готовых структурах будут другие поля), но этокажется невозможным с моей реализацией.

Как я могу реорганизовать код, чтобы иметь возможность включать типы страниц, как объявлено выше?

Ответы [ 2 ]

1 голос
/ 20 сентября 2019

Если данные вашей страницы предопределены и запечатаны с нуля, вам даже не понадобится protocol (это будет даже контрпродуктивно), просто увеличьте enum:

enum Page {
    case html(title: String, data: String?)
    case pdf(title: String)
    case links(title: String, array: [URL]) // or something else, it wasn't used in the example

    var title: String {
        switch(self) {
        case .html(let title, _), .pdf(let title), .links(let title, _):
            return title
        }
    }
}

var pageArray : [Page] = [] // no need to make it optional, btw

let test = Page.pdf(title: "title1")
pageArray.append(test)

let testtwo = Page.html(title: "title2", data: "hello")
pageArray.append(testtwo)

for page in pageArray {
    print (page.title)

    if case .html(_, let data) = page {
        print(data)
    }
}
0 голосов
/ 20 сентября 2019

Хорошо, я не понимаю, что вы пытаетесь сделать, но вот совет о том, что вы делаете, если это то, что вы ищете,

protocol PageDataProtocol {
    var data: String? {get}
}

protocol PageTitleProtocol {
    var title: String {get}
}

struct PDFData: PageTitleProtocol {
    var title: String
}

struct HTMLData: PageDataProtocol, PageTitleProtocol {
    var title: String
    var data: String?
}

var pageArray : [Any]? = []

let test = PDFData(title: "title1")
pageArray?.append(test)

let testtwo = HTMLData(title: "title2", data: "hello")
pageArray?.append(testtwo)


for page in pageArray! {
   if let page = page as? PageDataProtocol {
        print(page.data)
    }
    if let page = page as? PageTitleProtocol {
        print(page.title)
    }
}

Проверьте этонет нужды перечислять, и приведение к типу протокола для использования свойства всегда лучше, потому что вы могли бы иметь 100 соответствующих ему структур и классов, но вы не заботитесь о них, вы заботитесь о свойствах внутри, если бы они былитипа этого конкретного протокола, это правильное использование протокола.

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