首页 > 解决方案 > 根据泛型类型实现功能的泛型类

问题描述

我有一个泛型类,它需要根据泛型的类型返回一些数据。以下解决方案适用于具体实现,不适用于 CaseIteratable 等协议。有解决方法吗?即使在里面SomeThing我可以检查大小写可迭代也没问题,但编译器不允许这样做

struct SomeThing<T>: DoSomething {
    let value: T

    func doSomething() {
        if let doable = value as? DoSomething {
            doable.doSomething()
        }
    }
}

protocol DoSomething {
    func doSomething()
}

extension Bool: DoSomething {
    func doSomething() {
        "bool action"
    }
}

// Won't compile
extension CaseIterable: DoSomething where Self: RawRepresentable {
    func doSomething() {
        "bool action"
    }
}

我也尝试为某些东西添加扩展名,但最终遇到了同样的问题

extension SomeThing: DoSomething where T: Bool {}
extension SomeThing: DoSomething where T: CaseIteratable {}

标签: swift

解决方案


基于 Swift 文档

当您定义协议扩展时,您可以指定在扩展的方法和属性可用之前符合类型必须满足的约束。您可以通过编写通用 where 子句将这些约束写在您要扩展的协议的名称之后。有关通用 where 子句的更多信息,请参阅通用 Where 子句

协议扩展

struct SomeThing<T>: DoSomething {
    let value: T

    func doSomething() {
        if let doable = value as? DoSomething {
            doable.doSomething()
        }
    }
}

protocol DoSomething {
    func doSomething()
}

extension Bool: DoSomething {
    func doSomething() {
        "bool action"
    }
}

// this will compiles
extension CaseIterable where Self: RawRepresentable, Self.RawValue == Bool {
    func doSomething() {
        "bool action"
    }
}

extension CaseIterable where Self: DoSomething {}

这是 Github 问题的另一个答案

这是因为一致性需要一个约束,否则编译器认为它是一个继承。

资料来源:协议的扩展不能有继承条款

希望这会有所帮助


推荐阅读