首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Swift 4中的嵌套枚举

Swift 4中的嵌套枚举
EN

Stack Overflow用户
提问于 2019-01-13 10:15:53
回答 2查看 3.3K关注 0票数 0

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

代码语言:javascript
运行
复制
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
        }
    }
}

以下内容的输出:

代码语言:javascript
运行
复制
for type in HousingType.allCases {
    print(type.name)
}

是:

代码语言:javascript
运行
复制
Victorian House
Modern House
Standard House
Victorian Apartment
Modern Apartment
Standard Apartment
Victorian Mansion
Modern Mansion
Standard Mansion

和输出,用于

代码语言:javascript
运行
复制
let apartment = HousingType.Apartment(.Modern)
print(apartment.name)

是:

代码语言:javascript
运行
复制
Modern Apartment

我可以很容易地从枚举中获取数据并遍历所有的用例,但是正如您所看到的,为一个变量name遍历每个可能的用例需要大量的代码。当我添加代码来获取roomsbathrooms,或者添加额外的HousingSubType时,这个实现的长度变得非常长。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-13 12:04:47

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

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

代码语言:javascript
运行
复制
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
    ),
]
票数 5
EN

Stack Overflow用户

发布于 2019-01-28 14:30:13

虽然在不了解要建模的所有信息和使用该方法的要求的情况下很难推荐一种方法,但可以对样例枚举中使用的方法进行稍微修改,以减少所需的代码。

例如,这个实现似乎实现了您想要的相同的初始结果(它为HousingType.allCases打印相同的结果,并允许相同的创建和打印单个实例的名称)。但是,它使用了一种略微不同的方法来显著减少所需的代码行:

代码语言:javascript
运行
复制
enum HousingType: CaseIterable {
    case House(HousingSubType)
    case Apartment(HousingSubType)
    case Mansion(HousingSubType)

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

    static var allCases: [HousingType] {
        return Array(HousingSubType.allCases.map{ [HousingType.House($0), HousingType.Apartment($0), HousingType.Mansion($0) ] }.joined())
    }

    var name: String {
        switch self {
            case .House(let subtype): return subtype.rawValue + " House"
            case .Apartment(let subtype): return subtype.rawValue + " Apartment"
            case .Mansion(let subtype): return subtype.rawValue + " Mansion"
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54165576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档