- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个名为 ProgrammingLanguage
的枚举:
enum ProgrammingLanguage {
case Swift, Haskell, Scala
}
Programmer
的类具有以下属性:
let favouriteLanguages: ProgrammingLanguage = .Swift
let favouriteLanguages: ProgrammingLanguage = [.Swift, .Haskell]
OptionSetType
,但这样做时,我提出了以下 3 个错误:
SetAlgebraType
OptionSetType
RawRepresentable
case ProgrammingLanguage: String, OptionSetType {
case Swift, Haskell, Scala
}
SetAlgebraType
.
Int
修复它(这是有道理的,因为
RawRepresentable
协议(protocol)要求您实现签名
init(rawValue: Int)
的初始化程序)。但是,我对此并不满意;我希望能够轻松获得枚举的字符串表示。
OptionSetType
需要一个
Int
关联类型?
enum ProgrammingLanguage: Int, OptionSetType {
case Swift, Scala, Haskell
}
extension ProgrammingLanguage {
init(rawValue: Int) {
self.init(rawValue: rawValue)
}
}
let programmingLanguages: ProgrammingLanguage = [.Swift, .Scala]
最佳答案
编辑:我对我以前的自己当时没有提前说这件事感到惊讶,但是......而不是试图强制其他值类型进入 OptionSet
协议(protocol)(Swift 3 从名称中删除了 Type
),最好考虑使用这些类型的 API 并使用 Set
在适当的情况下收集。OptionSet
类型很奇怪。它们既是集合又不是集合——您可以从多个标志构造一个,但结果仍然是单个值。 (您可以做一些工作来找出与此类值等效的单个标志集合,但根据类型中可能的值,它可能不是唯一的。)
另一方面,能够拥有一个东西,或者多个独特的东西,对于 API 的设计很重要。您希望用户说他们最喜欢的不止一个,还是强制要求只有一个?您想要允许多少个“收藏夹”?如果用户声称拥有多个收藏夹,是否应该按照用户特定的顺序对它们进行排名?这些都是OptionSet
很难回答的问题。 -style 类型,但如果您使用 Set
则更容易类型或其他实际集合。
这个答案的其余部分 a) 是旧的,使用 Swift 2 名称,并且 b) 假设您正在尝试实现 OptionSet
无论如何,即使这对您的 API 来说是一个糟糕的选择...
见docs for OptionSetType
:
Supplies convenient conformance to
SetAlgebraType
for any type whoseRawValue
is aBitwiseOperationsType
.
OptionSetType
任何类型的一致性也采用
RawRepresentable
.但是,当且仅当关联的原始值类型符合
ArrayLiteralConvertible
时,您才能获得神奇的集合代数语法支持(通过运算符和
BitwiseOperationsType
一致性)。 .
String
,你运气不好——你没有获得集合代数的东西,因为
String
不支持按位运算。 (这里的“有趣”之处,如果你能这么称呼的话,就是你可以扩展
String
来支持
BitwiseOperationsType
,如果你的实现满足
axioms ,你可以使用字符串作为选项集的原始值.)
self.init(rawValue:)
来自
init(rawValue:)
一直锣直到它吹完堆栈。
OptionSetType
一致性,因为:
ProgrammingLanguage
枚举您说的是 ProgrammingLanguage
类型的值必须是 Swift
之一, Scala
, 或 Haskell
,而不是其他任何东西。 “Swift 和 Scala”的值不在该集合中。 OptionSetType
的底层实现基于整数位域。 “Swift 和 Haskell”值( [.Swift, .Haskell]
)实际上只是 .Swift.rawValue | .Haskell.rawValue
.如果您的原始值集不是位对齐的,这会导致麻烦。也就是说,如果 .Swift.rawValue == 1 == 0b01
, 和 .Haskell.rawValue == 2 == 0b10
,这些的按位或是 0b11 == 3
, 与 .Scala.rawValue
相同. OptionSetType
一致性,声明一个结构。
static let
声明您的类型的成员。
struct ProgrammingLanguage: OptionSetType {
let rawValue: Int
// this initializer is required, but it's also automatically
// synthesized if `rawValue` is the only member, so writing it
// here is optional:
init(rawValue: Int) { self.rawValue = rawValue }
static let Swift = ProgrammingLanguage(rawValue: 0b001)
static let Haskell = ProgrammingLanguage(rawValue: 0b010)
static let Scala = ProgrammingLanguage(rawValue: 0b100)
}
static let Swift = ProgrammingLanguage(rawValue: 1 << 0)
static let Haskell = ProgrammingLanguage(rawValue: 1 << 1)
static let Scala = ProgrammingLanguage(rawValue: 1 << 2)
关于swift - OptionSetType 和枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36819163/
我是一名优秀的程序员,十分优秀!