Swift 2:有没有办法在带有关联值的enum的switch语句中使用“默认”?

丹尼斯·金

我有一个递归枚举,其中大多数情况下具有相同类型的关联值:

indirect enum Location {
    case Title(String?)
    case Region(Location)
    case Area(Location, Location)
    case City(Location, Location)
    case Settlement(Location, Location)
    case Street(Location, Location)
    case House(Location, Location)
}

我想要做的是形成一个不错的字符串描述,其中将包括所有非零标题。

func getStringFromLocation(location: Location) -> String? {
    var parts: [String?] = []

    switch location {
    case .Title(let title): return title
    case .House(let title, let parent):
        parts.append(getStringFromLocation(parent))
        parts.append(getStringFromLocation(title))
    case .Street(let title, let parent):
        parts.append(getStringFromLocation(parent))
        parts.append(getStringFromLocation(title))
    case .Settlement(let title, let parent):
        parts.append(getStringFromLocation(parent))
        parts.append(getStringFromLocation(title))
    case .City(let title, let parent):
        parts.append(getStringFromLocation(parent))
        parts.append(getStringFromLocation(title))
    case .Area(let title, let parent):
        parts.append(getStringFromLocation(parent))
        parts.append(getStringFromLocation(title))
    case .Region(let title):
        parts.append(getStringFromLocation(title))
    }

    return parts
        .filter { $0 != nil }
        .map { $0! }
        .joinWithSeparator(", ")
}

问题是七种可能的情况中有五种是完全相同的,而且我有一堆复制粘贴的代码,但我认为这不好。如果我列举了一百个案例怎么办?

有什么办法可以写这样的东西吗?

switch location {
case .Title(let title): 
    parts.append(title)
case .Region(let title):
    parts.append(getStringFromLocation(title))
default (let title, let parent):
    parts.append(getStringFromLocation(parent))
    parts.append(getStringFromLocation(title))
}

...使用一些默认案例来处理所有类似案例?

罗布·纳皮尔

尽管我同意保罗的担心,即以Location这种方式嵌套很奇怪,但基本问题是可以解决的。就我个人而言,我不会用a来解决它default,我只是简化代码并使用Swift给我们提供的工具(例如CustomStringConvertible;我还在您的数据上贴上标签;这太使人混淆了两个Location含义完全不同的元素) :

indirect enum Location: CustomStringConvertible {
    case Title(String?)
    case Region(Location)
    case Area(title: Location, parent: Location)
    case City(title: Location, parent: Location)
    case Settlement(title: Location, parent: Location)
    case Street(title: Location, parent: Location)
    case House(title: Location, parent: Location)

    var description: String {

        func format(locs: (Location, Location)) -> String {
            return [locs.0, locs.1].map{$0.description}.filter{$0 != ""}.joinWithSeparator(", ")
        }

        switch self {
        case .Title(let title): return title ?? ""

        case .Region(let title): return "\(title)"

        case .House(let data):      return format(data)
        case .Street(let data):     return format(data)
        case .Settlement(let data): return format(data)
        case .City(let data):       return format(data)
        case .Area(let data):       return format(data)
        }
    }
}

请注意如何将整个元组卸载到中data您无需在模式匹配中将元组分开。枚举永远不会有多个关联的数据。他们总是只有一个:元组。(函数也是如此。所有函数都取一个值并返回一个值。该值可能恰好是一个元组。)

但是,如果您真的想摆脱这种重复return format(data),那么您可以通过Mirror(您可以通过解决很多事情Mirror。在执行此操作之前,您应该非常小心。这种情况只是重复的输入,而不是重复的逻辑。稍微重复的输入就不会造成很多复杂的操作。)

这是您的处理方式:

var description: String {
    switch self {
    case .Title(let title): return title ?? ""

    case .Region(let title): return "\(title)"

    default:
        let m = Mirror(reflecting: self)
        guard let locs = (m.children.first?.value as? (Location, Location)) else {
            preconditionFailure("Unexpected data in enum. Probably missing a case somewhere.")
        }
        return [locs.0, locs.1].map{$0.description}.filter{$0 != ""}.joinWithSeparator(", ")
    }
}

这里的教训是,枚举的第一个孩子是其所有数据的元组。

但是使用Mirror起来更加脆弱(注意,我打开了崩溃的可能性)。尽管这里的枚举可能是一个很好的工具,但您仍然可能需要重新考虑这个数据结构。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

有没有办法在最新的Swift 3快照中使用C可变参数函数?

来自分类Dev

有没有办法在最新的Swift 3快照中使用C可变参数函数?

来自分类Dev

带有关联值的Swift枚举

来自分类Dev

带有关联值的Swift枚举

来自分类Dev

有没有办法在Swift中更改NSTextView容器的字符串值?

来自分类Dev

有没有办法让Swift脚本使用多个文件

来自分类Dev

带有关联值的开关内部的Swift Mutation

来自分类Dev

没有关联值的引用Swift枚举成员

来自分类Dev

有没有办法在switch语句中访问不匹配的值?

来自分类Dev

有没有办法用Ansible自动化OpenStack Swift操作

来自分类Dev

有没有办法像C#中那样在Swift中锁定对象

来自分类Dev

有没有办法在Swift中以编程方式设置NSCollectionView?

来自分类Dev

有没有办法在Swift中获得_stable_通用类名?

来自分类Dev

单元测试:有没有办法查看Swift的代码覆盖率?

来自分类Dev

有没有办法摆脱Swift中数组的reduce函数?

来自分类Dev

有没有办法以编程方式更新帧(Swift)

来自分类Dev

有没有办法在Swift中为struct自动定义compare(`==`)函数?

来自分类Dev

有没有办法在Swift中将Array覆盖为String?

来自分类Dev

有没有办法在Swift中仅通过JSON部分创建对象?

来自分类Dev

Swift-有没有办法在串联字符串中包含单引号(')?

来自分类Dev

当 Swift 中满足特定条件时,有没有办法结束递归方法?

来自分类Dev

有没有办法在 Swift 3 Xcode 8 中首先完成异步任务?

来自分类Dev

有没有办法增加Swift中double类型的数量限制?

来自分类Dev

有没有办法让 Swift 编译器忽略错误?

来自分类Dev

有没有办法在 Swift 中按子数组的索引对数组进行排序?

来自分类Dev

如何在Swift中检查带有关联值的枚举的枚举大小写

来自分类Dev

如何创建带有关联值(如Swift枚举)的Java枚举?

来自分类Dev

将带有关联值的枚举存储在NSUserDefaults(Swift)中

来自分类Dev

尝试从API获取数据时出现“与键CodingKeys没有关联的值”错误-Swift

Related 相关文章

  1. 1

    有没有办法在最新的Swift 3快照中使用C可变参数函数?

  2. 2

    有没有办法在最新的Swift 3快照中使用C可变参数函数?

  3. 3

    带有关联值的Swift枚举

  4. 4

    带有关联值的Swift枚举

  5. 5

    有没有办法在Swift中更改NSTextView容器的字符串值?

  6. 6

    有没有办法让Swift脚本使用多个文件

  7. 7

    带有关联值的开关内部的Swift Mutation

  8. 8

    没有关联值的引用Swift枚举成员

  9. 9

    有没有办法在switch语句中访问不匹配的值?

  10. 10

    有没有办法用Ansible自动化OpenStack Swift操作

  11. 11

    有没有办法像C#中那样在Swift中锁定对象

  12. 12

    有没有办法在Swift中以编程方式设置NSCollectionView?

  13. 13

    有没有办法在Swift中获得_stable_通用类名?

  14. 14

    单元测试:有没有办法查看Swift的代码覆盖率?

  15. 15

    有没有办法摆脱Swift中数组的reduce函数?

  16. 16

    有没有办法以编程方式更新帧(Swift)

  17. 17

    有没有办法在Swift中为struct自动定义compare(`==`)函数?

  18. 18

    有没有办法在Swift中将Array覆盖为String?

  19. 19

    有没有办法在Swift中仅通过JSON部分创建对象?

  20. 20

    Swift-有没有办法在串联字符串中包含单引号(')?

  21. 21

    当 Swift 中满足特定条件时,有没有办法结束递归方法?

  22. 22

    有没有办法在 Swift 3 Xcode 8 中首先完成异步任务?

  23. 23

    有没有办法增加Swift中double类型的数量限制?

  24. 24

    有没有办法让 Swift 编译器忽略错误?

  25. 25

    有没有办法在 Swift 中按子数组的索引对数组进行排序?

  26. 26

    如何在Swift中检查带有关联值的枚举的枚举大小写

  27. 27

    如何创建带有关联值(如Swift枚举)的Java枚举?

  28. 28

    将带有关联值的枚举存储在NSUserDefaults(Swift)中

  29. 29

    尝试从API获取数据时出现“与键CodingKeys没有关联的值”错误-Swift

热门标签

归档