首页 > 解决方案 > 如何扩展添加计算静态变量的协议

问题描述

我想扩展 CaseIterable 协议,以便所有 CaseIterable 枚举都有一个random返回随机案例的静态变量。这是我尝试过的代码

public extension CaseIterable {
    static var random<T: CaseIterable>: T {
        let allCases = self.allCases
        return allCases[Int.random(n: allCases.count)]
    }
}

但这无法编译。有没有办法使用静态变量来实现这一点?或者如果没有,我将如何编写等效的静态函数?

ps Int.random 扩展为任何在家玩的人:

public extension Int {
    static func random(n: Int) -> Int {
        return Int(arc4random_uniform(UInt32(n)))
    }
}

标签: swift

解决方案


现有的答案对于如何修复它是正确的,但是为什么理解它可能同样有用。这不是你想的那样:

public extension CaseIterable {
    static var random<T: CaseIterable>: T {
        // ...
    }
}

这定义了一个属性 ,random它将返回一个 type 的值,它是调用者选择的符合 CaseIterable的T任何类型。例如,根据这个定义,我可以进行如下调用:

let direction: LayoutDirection = Axis.random

在这种情况下,Axis承诺它将返回 a LayoutDirection,因为这是调用者传递的T. 显然这不是你想要的。您的意思是,每个 CaseIterable 都可以返回其自己类型的随机值,并且正如另一个答案所示,您可以使用static var random: Self.

泛型类型参数(如T本例中)是参数。它们由调用者传递,而不是由实现者选择。


推荐阅读