【发布时间】:2014-08-09 19:33:10
【问题描述】:
我正在尝试定义一个需要实现 enum 和原始值 String 的协议。
我不相信目前可以强制使用 enum,而且我不确定我是否真的在乎,只要我可以致电 fromRaw()并收到String。
因此,我试图保持以下内容的简洁性,同时将Beta 限制为enum,其中原始值为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
【问题讨论】:
-
只是出于好奇,您检查了stackoverflow.com/questions/24031646/… 吗?
-
我做了,那里的答案描述了我在示例中展示的内容。