Zme*_*mey 2 generics bitvector bit-fields swift swift3
我正在尝试编写一个辅助函数,它将把位索引数组转换为符合 OptionSet 的类。
func getOptionSet<T: OptionSet>(bitIndexes: [Int64]) -> T {
var result: Int64 = 0
for index in bitIndexes {
result |= 1 << index
}
return T(rawValue: result) // error
}
Run Code Online (Sandbox Code Playgroud)
这无法编译:
Cannot invoke initializer for type 'T' with an argument list of type '(rawValue: Int64)'
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用 RawValue:
func getOptionSet<T: OptionSet>(bitIndexes: [T.RawValue]) {
var result = T.RawValue() // error
Run Code Online (Sandbox Code Playgroud)
这也不起作用:
Cannot invoke value of type 'T.RawValue.Type' with argument list '()'
Run Code Online (Sandbox Code Playgroud)
这可以做到吗?我需要对 T 添加额外的约束吗?
我知道可以重写这个函数以使用具体类型,但如果可能的话我想保持它的通用性。
你的代码中的问题是Int64和T.RawValue不相关并且可以是不同的类型。
但是每个无符号整数类型都可以从 and\n 转换为,因此可以通过限制为来UIntMax解决问题RawValueUnsignedInteger。
使用 @OOPer\ 的想法来定义自定义初始值设定项,这将是:
\n\nextension OptionSet where RawValue: UnsignedInteger {\n init(bitIndexes: [Int]) {\n var result: UIntMax = 0\n for index in bitIndexes {\n result |= 1 << UIntMax(index)\n }\n self.init(rawValue: RawValue(result))\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n也可以写成
\n\nextension OptionSet where RawValue: UnsignedInteger {\n init(bitIndexes: [Int]) {\n let result = bitIndexes.reduce(UIntMax(0)) {\n $0 | 1 << UIntMax($1)\n }\n self.init(rawValue: RawValue(result))\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n到目前为止我看到的所有选项集类型都有一个无符号整数\n类型作为原始值,但请注意,同样也适用于\nSignedInteger和IntMax。
例子:
\n\nstruct TestSet: OptionSet {\n let rawValue: UInt16\n init(rawValue: UInt16) {\n self.rawValue = rawValue\n }\n}\n\nlet ts = TestSet(bitIndexes: [1, 4])\nprint(ts) // TestSet(rawValue: 18)\nRun Code Online (Sandbox Code Playgroud)\n\n另请比较如何在 Swift 中枚举 OptionSetType?用于反向任务。
\n\n更新:从Swift 4 开始UnsignedInteger协议有一个
public static func << <RHS>(lhs: Self, rhs: RHS) -> Self where RHS : BinaryInteger\nRun Code Online (Sandbox Code Playgroud)\n\n方法,这样上面的代码就可以简化为
\n\nextension OptionSet where RawValue: UnsignedInteger {\n init(bitIndexes: [Int]) {\n self.init(rawValue: bitIndexes.reduce(0) { $0 | 1 << $1 })\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n无需中间转换为 \xe2\x80\x9cmaximal\xe2\x80\x9d 整数类型。
\n| 归档时间: |
|
| 查看次数: |
1192 次 |
| 最近记录: |