【问题标题】:Is there a way to combine switch and contains?有没有办法结合开关和包含?
【发布时间】:2018-10-20 14:29:28
【问题描述】:

假设我有三个包含扩展的集合:

let photos: Set = ["jpg", "png", "tiff"]
let videos: Set = ["mp4", "mov", "mkv"]
let audios: Set = ["mp3", "wav", "wma"]

和一个简单的枚举为:

enum FileType {
    case photo, video, audio, unknown
}

现在我要做的是实现一个函数,该函数根据传递给它的字符串和包含它的集合返回FileType 选项:

func getType(of file: String) -> FileType {
    if photos.contains(file) { return .photo }
    if videos.contains(file) { return .video }
    if audios.contains(file) { return .audio }

    return .unknown
}

它应该可以按预期工作,但我想知道是否有一种方法可以将 if 语句转换为 switch 情况(即使它会稍微改变逻辑),尤其是在使用枚举时 @987654328 @ 语句是避免错误的更好选择。

如果使用 switch 语句无法实现,我也将不胜感激任何优雅的替代方案。

【问题讨论】:

  • 不是您具体问题的真正答案,但我会定义一个 FileExtension 类型,该类型具有 fileType 属性和相应的文件类型,例如 gist.github.com/hamishknight/c211c63e321df33d18e9f90c72d4a20f
  • @Hamish 我完全同意你的看法。此外,某些扩展名可以是“音频”和“视频”。

标签: swift if-statement enums switch-statement contains


【解决方案1】:

我认为你的整个问题是你试图为每种类型维护 3 个独立的集合,而不是直接将它们连接到给定的文件类型:

enum FileType: String {
    case photo, video, audio, unknown
}

let extensions: [FileType: Set<String>] = [
    .photo: ["jpg", "png", "tiff"],
    .video: ["mp4", "mov", "mkv"],
    .audio: ["mp3", "wav", "wma"]
]

func getType(of file: String) -> FileType {
    return extensions.first { $0.value.contains(file) }?.key ?? .unknown
}

【讨论】:

    【解决方案2】:

    您可以为模式匹配运算符~=添加重载:

    func ~= <T> (pattern: Set<T>, value: T) -> Bool {
        return pattern.contains(value)
    }
    
    func getType(of file: String) -> FileType {
        switch file {
        case photos: return .photo
        case videos: return .video
        case audios: return .audio
        default: return .unknown
        }
    }
    

    【讨论】:

      【解决方案3】:

      这适用于您的情况

      let photos: Set = ["jpg", "png", "tiff"]
      let videos: Set = ["mp4", "mov", "mkv"]
      let audios: Set = ["mp3", "wav", "wma"]
      
      enum FileType {
          case photo, video, audio, unknown
      }
      
      func getType(of file: String) -> FileType {
      
         switch true {
      
         case photos.contains(file):
             return .photo
         case videos.contains(file):
             return .video
         case audios.contains(file):
             return .audio
         default:
             return .unknown
          }
      }
      
      print(getType(of: "mp4"))
      

      视频

      您可以打开true,然后当您有多个条件时,使用每个案例作为条件。

      【讨论】:

      • 是的,它是我能想到的唯一方法,它使用 switch 语句。虽然更喜欢你的实现
      • 我以前从未见过切换true...这是如何工作的?
      • @aheze 它只是反转条件,在有多个条件时使用。就像说什么时候是真的一样
      • 有道理,这很聪明!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 2015-04-05
      • 2011-02-23
      • 2012-03-05
      相关资源
      最近更新 更多