我正在尝试定义一个需要实现原始值为字符串的枚举类型的协议。
我不认为目前可以强制使用枚举类型,并且我也不确定我真的很关心,只要在后续过程中我可以调用
因此,我正在尝试保持以下代码的简洁性,同时限制
上述方法的问题在于允许使用其他原始值,因此以下内容是有效的:
为了解决这个问题,我目前正在做以下事情:
我不认为目前可以强制使用枚举类型,并且我也不确定我真的很关心,只要在后续过程中我可以调用
fromRaw()
并接收到字符串即可。因此,我正在尝试保持以下代码的简洁性,同时限制
Beta
为一个枚举类型且其原始值为String
。protocol Alpha {
typealias Beta: RawRepresentable
}
struct Gamma: Alpha {
enum Beta: String {
case Delta = "delta"
}
}
struct Eta<T: Alpha, U: RawRepresentable where T.Beta == U> {
let alpha: T
let beta: U
init(alpha: T, beta: U) {
self.alpha = alpha
self.beta = beta
println("beta is: \(beta.toRaw())")
}
}
let gamma = Gamma()
Eta(alpha: gamma, beta: .Delta) // "beta is delta"
上述方法的问题在于允许使用其他原始值,因此以下内容是有效的:
struct Epsilon: Alpha {
enum Beta: Int {
case Zeta = 6
}
}
let epsilon = Epsilon()
Eta(alpha: epsilon, beta: .Zeta) // "beta is 6"
为了解决这个问题,我目前正在做以下事情:
protocol StringRawRepresentable: RawRepresentable {
class func fromRaw(raw: String) -> Self?
}
protocol Alpha {
typealias Beta: StringRawRepresentable
}
struct Gamma: Alpha {
enum Beta: String, StringRawRepresentable {
case Delta = "delta"
}
}
// Type 'Epsilon' does not conform to protocol 'Alpha'
struct Epsilon: Alpha {
enum Beta: Int {
case Zeta = 6
}
}
struct Eta<T: Alpha, U: StringRawRepresentable where T.Beta == U> {
let alpha: T
let beta: U
init(alpha: T, beta: U) {
self.alpha = alpha
self.beta = beta
println("beta is: \(beta.toRaw())")
}
}
let gamma = Gamma()
Eta(alpha: gamma, beta: .Delta) // "beta is delta"
有没有一种方法可以在原始示例中以不同的方式声明typealias
,以将RawRepresentable
限制为String
?
更新
指定U:RawRepresentable where U.Raw == String
似乎很有希望,所以我尝试了一下:
protocol Alpha {
typealias Beta: RawRepresentable
}
struct Gamma: Alpha {
enum Beta: String {
case Delta = "delta"
}
}
struct Eta<T: Alpha, U: RawRepresentable where T.Beta == U, U.Raw == String> {
let alpha: T
let beta: U
init(alpha: T, beta: U) {
self.alpha = alpha
self.beta = beta
// Execution was interrupted, reason: EXC_BAD_ACCESS (code=EXC_I386_GPFLT).
println("beta is: \(beta.toRaw())")
}
}
let gamma = Gamma()
Eta(alpha: gamma, beta: .Delta) // "beta is delta"
struct Epsilon: Alpha {
enum Beta: Int {
case Zeta = 6
}
}
let epsilon = Epsilon()
Eta(alpha: epsilon, beta: .Zeta) // Error only occurs when this is executed
虽然这样技术上防止使用除了String
以外的其他类型,但我正在寻找一种编译时约束,而这似乎会引起运行时异常。
如果可能的话,我更希望由协议来强制执行这一点,而不是消费者需要检查.Raw == String
。