You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将带关联值的枚举模式存储在数组中?

当然可以实现!不过带关联值的枚举和你原来的简单枚举逻辑不一样——每个带关联值的枚举实例都是具体的实例(比如.audio(duration: 10)和.audio(duration: 20)是完全不同的实例),没法直接把「匹配模式」(比如“所有音频类型”“时长超过10秒的音频”)存进数组里。我们可以换个思路,通过闭包或者自定义匹配类型来搞定这个需求。

先改造你的枚举(添加关联值)

首先把原来的简单枚举改成带关联值的版本:

import CoreGraphics

enum MessageType {
    case audio(duration: TimeInterval)
    case photo(resolution: CGSize)
    case text(content: String)
}

方案一:用闭包数组封装匹配逻辑

我们可以把「是否能处理」的判断逻辑封装成闭包,存进Handler的数组里,这样既能匹配任意case类型,也能匹配带特定关联值条件的消息:

class Handler {
    private let matchers: [(MessageType) -> Bool]
    
    // 基础构造方法:直接传入匹配闭包数组
    init(matchers: [(MessageType) -> Bool]) {
        self.matchers = matchers
    }
    
    // 便捷构造方法:匹配任意指定的case类型(忽略关联值)
    convenience init(allowedCases: [MessageType]) {
        let matchers = allowedCases.map { targetCase in
            return { message in
                // 通过模式匹配判断是否属于同一case(不管关联值)
                switch (message, targetCase) {
                case (.audio, .audio): return true
                case (.photo, .photo): return true
                case (.text, .text): return true
                default: return false
                }
            }
        }
        self.init(matchers: matchers)
    }
    
    func canHandle(_ message: MessageType) -> Bool {
        // 只要有一个闭包返回true,就说明能处理
        return matchers.contains { $0(message) }
    }
}

用法示例

  1. 匹配任意音频和照片类型(忽略关联值)
// 这里传入的关联值只是占位,我们只关心case类型
let basicHandler = Handler(allowedCases: [.audio(duration: 0), .photo(resolution: .zero)])
print(basicHandler.canHandle(.audio(duration: 15))) // 输出 true
print(basicHandler.canHandle(.text(content: "Hello World"))) // 输出 false
  1. 匹配带特定条件的消息(比如时长>10秒的音频)
let customHandler = Handler(matchers: [
    // 匹配时长超过10秒的音频
    { message in
        if case .audio(let duration) = message, duration > 10 {
            return true
        }
        return false
    },
    // 匹配包含"紧急"关键词的文本消息
    { message in
        if case .text(let content) = message, content.contains("紧急") {
            return true
        }
        return false
    }
])

print(customHandler.canHandle(.audio(duration: 12))) // 输出 true
print(customHandler.canHandle(.text(content: "紧急通知:系统维护"))) // 输出 true
print(customHandler.canHandle(.photo(resolution: CGSize(width: 100, height: 100)))) // 输出 false

方案二:自定义模式枚举(更清晰易读)

如果觉得闭包不够直观,我们可以专门定义一个MessagePattern枚举,用来表示各种匹配模式,代码可读性会更好:

enum MessagePattern {
    // 匹配任意对应类型的消息
    case anyAudio
    case anyPhoto
    case anyText
    // 匹配带特定条件的消息
    case audioWithMinDuration(TimeInterval)
    case photoWithMinResolution(width: CGFloat, height: CGFloat)
    case textContaining(String)
    
    // 判断当前模式是否匹配某条消息
    func matches(_ message: MessageType) -> Bool {
        switch (self, message) {
        case (.anyAudio, .audio): return true
        case (.anyPhoto, .photo): return true
        case (.anyText, .text): return true
        case (.audioWithMinDuration(let min), .audio(let duration)):
            return duration >= min
        case (.photoWithMinResolution(let minW, let minH), .photo(let res)):
            return res.width >= minW && res.height >= minH
        case (.textContaining(let substr), .text(let content)):
            return content.contains(substr)
        default: return false
        }
    }
}

class Handler {
    private let patterns: [MessagePattern]
    
    init(patterns: [MessagePattern]) {
        self.patterns = patterns
    }
    
    func canHandle(_ message: MessageType) -> Bool {
        return patterns.contains { $0.matches(message) }
    }
}

用法示例

let patternHandler = Handler(patterns: [
    .audioWithMinDuration(10),
    .textContaining("urgent")
])

print(patternHandler.canHandle(.audio(duration: 15))) // 输出 true
print(patternHandler.canHandle(.text(content: "Urgent action required!"))) // 输出 true
print(patternHandler.canHandle(.photo(resolution: CGSize(width: 1920, height: 1080)))) // 输出 false

总结

带关联值的枚举不能直接把「模式」存进数组,但我们可以通过闭包封装匹配逻辑或者自定义模式枚举的方式,实现更灵活的消息处理判断。两种方案各有优劣:闭包更灵活,适合快速实现复杂逻辑;自定义模式枚举可读性更强,适合团队协作和长期维护。

内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:45:44