Swift 4 中的嵌套枚举

Blu*_*Guy 0 enums swift

当前从长嵌套枚举中提取数据的实现似乎非常乏味,并且维护这种结构很费力。下面是我所拥有的一个实现示例,只是想要一些输入,这是否真的是从这些枚举中提取数据的正确方法

import UIKit
import Foundation

enum HousingType {
    case House(HousingSubType)
    case Apartment(HousingSubType)
    case Mansion(HousingSubType)

    enum HousingSubType: CaseIterable {
        case Victorian
        case Modern
        case Standard
    }

    var name: String {
        switch self {
        case let .House(subtype):
            switch subtype {
            case .Modern:
                return Structure.House.Modern.name
            case .Standard:
                return Structure.House.Standard.name
            case .Victorian:
                return Structure.House.Victorian.name
            }
        case let .Apartment(subtype):
            switch subtype {
            case .Modern:
                return Structure.Apartment.Modern.name
            case .Standard:
                return Structure.Apartment.Standard.name
            case .Victorian:
                return Structure.Apartment.Victorian.name
            }
        case let .Mansion(subtype):
            switch subtype {
            case .Modern:
                return Structure.Mansion.Modern.name
            case .Standard:
                return Structure.Mansion.Standard.name
            case .Victorian:
                return Structure.Mansion.Victorian.name
            }
        }
    }

    static var allCases: [HousingType] {
        return
            HousingType.HousingSubType.allCases.map(HousingType.House)
                + HousingType.HousingSubType.allCases.map(HousingType.Apartment)
                + HousingType.HousingSubType.allCases.map(HousingType.Mansion)
    }
}

enum Structure {
    enum House {
        enum Victorian {
            static let name = "Victorian House"
            static let rooms = 4
            static let bathrooms = 1
        }
        enum Modern {
            static let name = "Modern House"
            static let rooms = 4
            static let bathrooms = 4
        }
        enum Standard {
            static let name = "Standard House"
            static let rooms = 4
            static let bathrooms = 2
        }
    }

    enum Apartment {
        enum Victorian {
            static let name = "Victorian Apartment"
            static let rooms = 2
            static let bathrooms = 1
        }
        enum Modern {
            static let name = "Modern Apartment"
            static let rooms = 2
            static let bathrooms = 2
        }
        enum Standard {
            static let name = "Standard Apartment"
            static let rooms = 2
            static let bathrooms = 1
        }
    }

    enum Mansion {
        enum Victorian {
            static let name = "Victorian Mansion"
            static let rooms = 10
            static let bathrooms = 3
        }
        enum Modern {
            static let name = "Modern Mansion"
            static let rooms = 10
            static let bathrooms = 10
        }
        enum Standard {
            static let name = "Standard Mansion"
            static let rooms = 10
            static let bathrooms = 6
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

for type in HousingType.allCases {
    print(type.name)
}
Run Code Online (Sandbox Code Playgroud)

是:

Victorian House
Modern House
Standard House
Victorian Apartment
Modern Apartment
Standard Apartment
Victorian Mansion
Modern Mansion
Standard Mansion
Run Code Online (Sandbox Code Playgroud)

并输出

let apartment = HousingType.Apartment(.Modern)
print(apartment.name)
Run Code Online (Sandbox Code Playgroud)

是:

Modern Apartment
Run Code Online (Sandbox Code Playgroud)

我可以轻松地从枚举中获取数据并遍历所有情况,但正如您所看到的,要遍历单个变量的每种可能情况需要大量代码name。我添加代码来获得roomsbathrooms或者额外HousingSubType添加,这个实现的长度变得非常长。

有没有更好的方法来获取变量name而不必通过一系列 switch 语句显式写出每个可能的情况?在尝试拥有一系列各种类型、子类型、子子类型等的静态变量时,我应该研究完全不同的实现吗?

OOP*_*Per 5

我可能遗漏了您真正想做的事情,但我通常不使用嵌套类型来表示需要动态解析和访问的数据结构。

看到你的示例代码,我会使用字典。

enum HousingType: Hashable {
    case house(HousingSubType)
    case apartment(HousingSubType)
    case mansion(HousingSubType)

    enum HousingSubType: CaseIterable {
        case victorian
        case modern
        case standard
    }

    var name: String {
        return structures[self]!.name
    }

    static var allCases: [HousingType] {
        return
            HousingType.HousingSubType.allCases.map(HousingType.house)
                + HousingType.HousingSubType.allCases.map(HousingType.apartment)
                + HousingType.HousingSubType.allCases.map(HousingType.mansion)
    }
}

struct Structure {
    let name: String
    let rooms: Int
    let bathrooms: Int
}

let structures: [HousingType: Structure] = [
    .house(.victorian): Structure(
        name: "Victorian House",
        rooms: 4,
        bathrooms: 1
    ),
    .house(.modern): Structure(
        name: "Modern House",
        rooms: 4,
        bathrooms: 4
    ),
    .house(.standard): Structure(
        name: "Standard House",
        rooms: 4,
        bathrooms: 2
    ),
    .apartment(.victorian): Structure(
        name: "Victorian Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .apartment(.modern): Structure(
        name: "Modern Apartment",
        rooms: 2,
        bathrooms: 2
    ),
    .apartment(.standard): Structure(
        name: "Standard Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .mansion(.victorian): Structure(
        name: "Victorian Mansion",
        rooms: 10,
        bathrooms: 3
    ),
    .mansion(.modern): Structure(
        name: "Modern Mansion",
        rooms: 10,
        bathrooms: 10
    ),
    .mansion(.standard): Structure(
        name: "Standard Mansion",
        rooms: 10,
        bathrooms: 6
    ),
]
Run Code Online (Sandbox Code Playgroud)