gpt4 book ai didi

swift - 在 Swift 中,如何指定将 RawRepresentable 限制为 String 的类型别名?

转载 作者:IT王子 更新时间:2023-10-29 05:37:13 27 4
gpt4 key购买 nike

我正在尝试定义一个协议(protocol),该协议(protocol)需要一个具有原始值 Stringenum 来实现。

我不相信目前有可能强制使用 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 以外的任何内容,但我正在寻找编译时约束,这似乎会导致运行时异常。

如果可能的话,我更希望由协议(protocol)强制执行,而不是消费者需要检查 .Raw == String

最佳答案

只是补充一下,因为它有点旧,您更新的示例现在可以在 swift 2+ 中运行,并且会在编译时提示 .Zeta 是不明确的,除非它是 String 类型。

您还可以将检查放在协议(protocol)扩展的模式匹配中。例如:

extension SequenceType where Generator.Element:RawRepresentable,
Generator.Element.RawValue == String {
func toStringArray() -> [String] {
return self.map { $0.rawValue }
}
}

关于swift - 在 Swift 中,如何指定将 RawRepresentable 限制为 String 的类型别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25222285/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com