Вызов внешних функций класса изнутри функций ENUM - PullRequest
0 голосов
/ 05 декабря 2018

В последнее время у меня возникали некоторые нерегулярные проблемы с ENUMS , и я задавался вопросом, безопасно ли / разрешено ли вызывать функции из внешних классов в качестве значений в функциях ENUM (не необработанные значения). Вот пример:

enum pageData: Int {
    case page1
    case page2
    case page3

    static let pageGroup = [page1, page2, page3]

    func initPage(caption: String = "") -> myCustomType {
      var mctData: myCustomType!

      switch self {
        case .page1:
          let text = (caption.isEmpty) ? extClass.getCaptionFunc("page1") : caption
          mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
        case .page2:
          let text = (caption.isEmpty) ? extClass.getCaptionFunc("page2") : caption
          mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/03"))
        default: ()
      }

    return mctData  
  }
}

Существует два отдельных примера функций (extClass.getCaptionFunc () & extClass.formatDateFunc ()) , вызываемых в Переключите регистр в ENUM для заполнения необходимых данных, которые будут возвращены функцией ENUM initPage () .

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

Спасибоза любой отзыв.

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Вот предложенный рефакторинг, основанный на комментариях выше.Если существует некоторая фиксированная связь между значением enum и заголовком, возвращаемым getCaptionFunc или датой из formatDateFunc, то вы можете подумать о том, должны ли эти функции быть реализованы в enum, но не зная вашего намерения, я не могу быть уверен (например, если страница 1 должнавсегда иметь заголовок «Страница 1», если не переопределено, тогда рассмотрите возможность присвоения enum строкового свойства, равного таковому через switch self).И если это так, то, возможно, extClass.initPage совершенно не нужен, и вы можете дать myCustomType конструктор, который принимает параметр enum.

enum pageData: Int {
  case page1
  case page2
  case page3

  static let pageGroup = [page1, page2, page3]
}

class extClass
{
  func initPage(page: pageData, caption: String = "") -> myCustomType {
    let text = caption.isEmpty ? getCaptionFunc(page) : caption 
    return myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
  }

  func getCaptionFunc(page: pageData) -> String {       
    switch page {
    case .page1:
      return "Page 1 Caption"
    case .page2:
      return "Page 2 Caption"
    ...
  }
}
0 голосов
/ 05 декабря 2018

В: Безопасно ли это?

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

Если бы это был обзор кода, я быскажем, использование неявно развернутого myCustomType! - опасный выбор.Ваша функция должна возвращать myCustomType, поэтому она должна действительно делать это в каждом случае, и неявно развернутая переменная принесет больше вреда, чем пользы.

Кроме того, я не вижу здесь необходимости в default случае.Позвольте swift выполнить его исчерпывающую проверку, чтобы вы знали, когда забыли реализовать кейс.Использование default подрывает это.С тем, что вы написали, вызов pageData.page3.initPage() приведет к сбою программы, потому что нет никакого случая для .page3, поэтому неявно развернутый mctData будет равен нулю.

Если вам абсолютно необходимо просто "замолчать""компилятор, вы можете предоставить fatalError() как реализацию любого случая, который вы пока не можете реализовать.Это было бы предпочтительнее в моей книге.

О статической функции: хотя в этом нет технической проблемы, это не будет моим подходящим решением.Трудно сказать наверняка, потому что я не знаю, что делает этот код, но я, вероятно, начну с этой реализации внутри класса pageData как вычисляемое свойство, например:

var defaultCaption: String {
    switch self {
    case .page1: // something, something "page1"
    // etc. for the rest of the cases
    }
}

Наконецтот факт, что все имена классов и констант не имеют заглавных букв (например, PageData, MyCustomType`), делает приведенный здесь код очень необычным и несколько сложным для чтения.Я бы посоветовал взглянуть на язык Рекомендации по разработке API , если вы этого еще не сделали.Следование стандартам сообщества облегчит выполнение вашего кода для тех, кто еще не знаком с ним.Включая людей на переполнение стека :)

0 голосов
/ 05 декабря 2018

Что вы имеете в виду «безопасно»?Ваш код содержит неверный синтаксис.Не используйте принудительно развернутые значения myCustomType!.

  1. Используйте правильный регистр> Отображение строковых значений с помощью :String

  2. Используйте правильный синтаксис кодадля pageGroup

  3. Использовать полный переключатель

enum pageData: String {
    case page1
    case page2
    case page3
static let pageGroup: pageData = [.page1, .page2, .page3]

    func initPage(caption: String = "") -> myCustomType {
      var mctData: myCustomType

      switch self {
        case .page1:
          let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption
          mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
        case .page2:
          let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption
          mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/03"))
        case .page3:
let text = caption.isEmpty ? extClass.getCaptionFunc(rawValue) : caption
          mctData = myCustomType(param1: text, param2: extClass.formatDateFunc("2018/12/01"))
      }

    return mctData  
  }
}

А как насчет вашего вопроса?В вашем случае нет разницы между такими методами и вычисляемыми переменными.extClass.getCaptionFunc в порядке.

...