首页 > 解决方案 > 在 Swift 中,您能否创建一个协议,该协议仅在关联类型的特定条件成立时才需要特定函数?

问题描述

我想表达一个类似于以下两个都无法编译的片段的 Swift 协议。

尝试1:

protocol AbstractFunction {
    associatedtype Domain
    associatedtype Codomain

    func apply(_ x: Domain) -> Codomain

    static var identity: Self where Domain == Codomain { get }
}

尝试2:

protocol AbstractFunction {
    associatedtype Domain
    associatedtype Codomain

    func apply(_ x: Domain) -> Codomain

    static func identity() -> Self where Domain == Codomain { get }
}

第一个在 Swift 语法中甚至无效,而第二个则以 'where' clause cannot be attached to a non-generic declaration.

这两个例子都试图表达一个协议,该协议描述不是实际函数类型实例的函数(A) -> B。如果有类型Vector2and Vector3,可以想象创建类型Matrix2x2,Matrix2x3Matrix3x3并使它们符合AbstractFunction协议。的域MatrixNxMVectorM,共域是VectorN。方阵有一个单位矩阵,但是当域和余域不同时,单位矩阵(或真正的单位函数)的概念没有意义。

因此,我希望协议AbstractFunction要求符合类型以提供身份,但仅在Domain == Codomain. 这可能吗?

标签: swiftswift-protocolsassociated-types

解决方案


您可以通过将第二个更严格的协议声明为:

protocol AbstractFunction {
    associatedtype Domain
    associatedtype Codomain

    func apply(_ x: Domain) -> Codomain
}

protocol AbstractEndofunction: AbstractFunction where Codomain == Domain {
    static var identity: Self { get }
}

Int -> Int 函数的示例:

final class IntFunction: AbstractEndofunction {
    typealias Domain = Int

    static var identity = IntFunction { $0 }

    private let function: (Int) -> Int

    init(_ function: @escaping (Int) -> Int) {
        self.function = function
    }

    func apply(_ x: Int) -> Int {
        return function(x)
    }
}

推荐阅读