Как получить доступ к ассоциированному перечислению в общем виде в Swift - PullRequest
0 голосов
/ 11 сентября 2018

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

  Struct SampleClass {

       enum Country: String {
        case US(cityList: ChianCityList)
        case Chian(cityList: USCityList)
      }
      enum ChianCityList {
        case Bijing
        case Shanghai

         static var allCases = [.Bijing, .Shanghai]
      }
      enum USCityList {
        case NewYork
        case LA

        static var allCases = [.NewYork, .LA]

        var isCaptial:Bool
      }

      var country: Country

      var allCityList: [?] {
       switch self.conuntry {
       case Chian
         return CityList.allCases
       case US
         return USCityList.allCases

      }

      init(country: Country)
      {
         self.country = Country
      }
  }

Теперь я не знаю, какой будет тип возвратаиз var 'allCityList'.Я хочу, чтобы это было общим.во-вторых, я не хочу называть «allCases» для каждого перечисления.Есть ли способ сделать его более общим?Это просто простой пример, есть много таких сценариев.Как 'isCaptial'.Как я могу сделать его более общим, чтобы в зависимости от страны, которую я могу узнать?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

В настоящее время USCityList и ChinaCityList являются двумя отдельными типами. Если вы возвращаете один тип, вы не можете вернуть другой. У вас есть два варианта.

enum ChianCityList {
    case Bijing
    case Shanghai

     static var allCases = [.Bijing, .Shanghai]
  }
enum USCityList {
    case NewYork
    case LA

    static var allCases = [.NewYork, .LA]

    var isCaptial:Bool
}

Вариант 1: преобразовать тот, который вы в настоящее время возвращаете, к тому же типу и сделать указанный тип как тип возврата

Пример:

enum ChianCityList: String, CaseIterable {
    case Bijing
    case Shanghai
}
enum USCityList: String, CaseIterable {
    case NewYork
    case LA

    var isCaptial:Bool
}

extension CaseIterable {
    var allCasesToStrings: [String] {
    return allCases.map{ String(describing: $0) }
}

var allCityList: [String] {
   switch self.conuntry {
   case Chian
     return CityList.allCasesToStrings
   case US
     return USCityList.allCasesToStrings
}

Вариант 2: привести оба типа в соответствие с одним и тем же протоколом, а затем вернуть экземпляр указанного протокола.

Пример:

protocol CityList {
    var cityList: [String] { get }
    Var capitalCity: String { get }
}

// Have both implement the protocol

var allCityList: CityList {
   switch self.conuntry {
   case Chian
     return CityList.cityList
   case US
     return USCityList.cityList
}
0 голосов
/ 11 сентября 2018

Для вашего примера я бы не использовал enum с.Это потому, что вы хотите хранить дополнительную информацию о городах (например, если это столица).Вместо этого я бы использовал struct с именем City, который инкапсулирует всю вашу информацию.Тогда вы можете иметь переменные chinaCities и usCities, которые являются массивом всех соответствующих городов.

Если бы вы действительно хотели принудительно использовать enum s, я бы создал одного гиганта enum называется City и хранит массив City s в двух отдельных переменных, чтобы различать их местоположение.

enum City: String {
    case beijing = "beijing"
    case newYork = "new york"
}

Конечно, если вы сделаете это, вам также придется проделать дополнительную работу, чтобыотслеживать, является ли город переменной.Одним из способов достижения этого является наличие функции, которая принимает City enum и возвращает true или false в зависимости от того, является ли она заглавной.

В качестве примечания япросто хотел отметить, что вы написали China и Beijing неправильно.Надеюсь, это поможет!

...