swift - 如何扩展添加计算静态变量的协议
问题描述
我想扩展 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)))
}
}
解决方案
现有的答案对于如何修复它是正确的,但是为什么理解它可能同样有用。这不是你想的那样:
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
本例中)是参数。它们由调用者传递,而不是由实现者选择。
推荐阅读
- php - PHPDeployer:根据主机为本地任务设置变量?
- c# - 执行处理程序的子请求时出错(仅在服务器上部署的应用程序)
- c# - 在 NumericUpDown 值更改时启用 GroupBox
- azure - 函数应用部署得到 403 错误和扩展代码 01020
- typescript - 从没有“as const”的数组创建类型元组
- javascript - JavaScript replace() 方法替换错误字符
- tensorflow - Keras model_to_estimator 不在 estimator.train 上记录指标,而是在 estimator.evaluate 上记录
- swift - 当视图控制器从 nib 文件加载时,以模态方式在当前上下文中呈现视图控制器
- mysql - MariaDB/Galera:将 MariaDB 10.4 节点连接到 MariaDB 10.1 集群是否安全?
- android - Cordova 不断用默认的 Hello World 应用程序替换我的代码