您可以利用SWIFT generics来实现您的目标.引入一个通用的Index
类型,如下所示:
struct Index<T>: RawRepresentable {
let rawValue: Int
init(rawValue: Int) { self.rawValue = rawValue }
init(_ rawValue: Int) { self.rawValue = rawValue }
}
然后像这样使用它:
func getHuman(at index: Index<Human>) -> Human { ... }
func getRobot(at index: Index<Robot>) -> Robot { ... }
getHuman(at: Index(1))
getRobot(at: Index(2))
文字索引
在使用literal indices时,您甚至可以使用ExpressibleByIntegerLiteral
协议来提供一些语法糖分:
extension Index: ExpressibleByIntegerLiteral {
public init(integerLiteral value: Int) { self.rawValue = value }
}
例如:
getHuman(at: 1)
getRobot(at: 2)
但以下代码将not构建,因此该解决方案仍然是类型安全的:
let someIndex = 123
getHuman(at: someIndex)
error: cannot convert value of type 'Int' to expected argument type 'Index<Human>'
个
可比指数
正如 comments 中所建议的,我们还可以添加Comparable
一致性(例如,这样您就可以在符合标准Collection
协议的类型中使用Index
struct 作为索引):
extension Index: Comparable {
static func < (lhs: Index, rhs: Index) -> Bool {
lhs.rawValue < rhs.rawValue
}
}
示例:
Index<Human>(1) < Index<Human>(2) // true