- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
2015 年 8 月 28 日更新:
这将在 Swift 2 中解决
见 Twitter response from Swift compiler developer
2015 年 10 月 23 日更新:
使用 Swift 2 泛型,您仍然无法获得 rawValue。你可以得到相关的值。
原问题:
我有一些 generic reflection code写得很快。在该代码中,我无法获取基于枚举的属性的值。问题归结为我无法执行 .rawValue
在类型为 Any
的属性值上. Swift 反射代码将返回枚举类型的值 Any
.那么如何从 Any 到 AnyObject,它是枚举的 rawValue。
到目前为止,我发现的唯一解决方法是使用协议(protocol)扩展所有枚举。您可以在下面看到使用此变通方法没问题的单元测试。
有没有办法在不向原始枚举中添加代码的情况下解决这个问题?
对于我的反射代码,我需要 getRawValue
方法签名保持原样。
class WorkaroundsTests: XCTestCase {
func testEnumToRaw() {
let test1 = getRawValue(MyEnumOne.OK)
XCTAssertTrue(test1 == "OK", "Could nog get the rawvalue using a generic function")
let test2 = getRawValue(MyEnumTwo.OK)
XCTAssertTrue(test2 == "1", "Could nog get the rawvalue using a generic function")
let test3 = getRawValue(MyEnumThree.OK)
XCTAssertTrue(test3 == "1", "Could nog get the rawvalue using a generic function")
}
enum MyEnumOne: String, EVRawString {
case NotOK = "NotOK"
case OK = "OK"
}
enum MyEnumTwo: Int, EVRawInt {
case NotOK = 0
case OK = 1
}
enum MyEnumThree: Int64, EVRaw {
case NotOK = 0
case OK = 1
var anyRawValue: AnyObject { get { return String(self.rawValue) }}
}
func getRawValue(theEnum: Any) -> String {
// What can we get using reflection:
let mirror = reflect(theEnum)
if mirror.disposition == .Aggregate {
print("Disposition is .Aggregate\n")
// OK, and now?
// Thees do not complile:
//return enumRawValue(rawValue: theEnum)
//return enumRawValue2(theEnum )
if let value = theEnum as? EVRawString {
return value.rawValue
}
if let value = theEnum as? EVRawInt {
return String(value.rawValue)
}
}
var valueType:Any.Type = mirror.valueType
print("valueType = \(valueType)\n")
// No help from these:
//var value = mirror.value --> is just theEnum itself
//var objectIdentifier = mirror.objectIdentifier --> nil
//var count = mirror.count --> 0
//var summary:String = mirror.summary --> "(Enum Value)"
//var quickLookObject = mirror.quickLookObject --> nil
let toString:String = "\(theEnum)"
print("\(toString)\n")
return toString
}
func enumRawValue<E: RawRepresentable>(rawValue: E.RawValue) -> String {
let value = E(rawValue: rawValue)?.rawValue
return "\(value)"
}
func enumRawValue2<T:RawRepresentable>(rawValue: T) -> String {
return "\(rawValue.rawValue)"
}
}
public protocol EVRawInt {
var rawValue: Int { get }
}
public protocol EVRawString {
var rawValue: String { get }
}
public protocol EVRaw {
var anyRawValue: AnyObject { get }
}
最佳答案
不幸的是,目前这在 Swift 中看起来不太可能,但是我已经考虑了您的问题一段时间,我将提出 Swift 团队可以帮助您解决此问题的 3 种方法。
Any
value 以查看它是否是枚举,如果是,您想查看它是否具有原始值。 rawValue
属性应该可以通过以下代码访问:let mirror = reflect(theEnum) // theEnum is of Any type
for i in 0..<mirror.count {
if mirror[i].0 == "rawValue" {
switch mirror[i].1.value {
case let s as String:
return s
case let csc as CustomStringConvertible:
return csc.description
default:
return nil
}
}
}
count
的
0
.我真的认为这是 Swift 团队在实现
Swift._EnumMirror
时的疏忽。 ,我将就此事提交雷达报告。
rawValue
绝对是合法属性(property)。这是一个奇怪的场景,因为枚举不允许具有其他存储属性。此外,您的枚举声明从未明确符合
RawRepresentable
,也不声明
rawValue
属性(property)。编译器只会在您输入
enum MyEnum: String
时推断出或
: Int
或者什么。在我的测试中,似乎属性是在协议(protocol)中定义还是关联类型的实例无关紧要,它仍然应该是镜像中表示的属性。
RawRepresentable
因为 Swift 不知道 rawValue
是什么类型的属性(property)会回来。语法如 RawRepresentable<where RawValue == String>
是可以想象的,或者也许 protocol<RawRepresentable where RawValue == String>
.如果这是可能的,您可以尝试通过 switch 语句转换为类型,如下所示:switch theEnum {
case let rawEnum as protocol<RawRepresentable where RawValue == String>:
return rawEnum.rawValue
// And so on
}
RawRepresentable
,Swift 编译器告诉您只能在泛型函数中使用它,但是当我查看您的代码时,这只会让您陷入困境。泛型函数在编译时需要类型信息才能工作,而这正是您无法使用的
Any
实例。
MyGenericStruct<MyType>
和
MyGenericClass<MyType>
是合法专用的具体类型,您可以对其进行运行时检查并强制转换为。然而,Swift 团队可能有充分的理由不想用协议(protocol)来做到这一点。协议(protocol)的专门版本(即具有已知关联类型的协议(protocol)引用)仍然不是具体类型。我不会为这种能力屏住呼吸。我认为这是我提出的解决方案中最弱的一个。
rawValue
上提供,我想为什么不实现我自己的通用镜像:struct RawRepresentableMirror<T: RawRepresentable>: MirrorType {
private let realValue: T
init(_ value: T) {
realValue = value
}
var value: Any { return realValue }
var valueType: Any.Type { return T.self }
var objectIdentifier: ObjectIdentifier? { return nil }
var disposition: MirrorDisposition { return .Enum }
var count: Int { return 1 }
subscript(index: Int) -> (String, MirrorType) {
switch index {
case 0:
return ("rawValue", reflect(realValue.rawValue))
default:
fatalError("Index out of range")
}
}
var summary: String {
return "Raw Representable Enum: \(realValue)"
}
var quickLookObject: QuickLookObject? {
return QuickLookObject.Text(summary)
}
}
RawRepresentable
成为
Reflectable
这样我们就可以先投
theEnum as Reflectable
(不需要关联类型)然后拨打
reflect(theEnum)
给我们我们很棒的定制镜子:
extension RawRepresentable: Reflectable {
func getMirror() -> MirrorType {
return RawRepresentableMirror(self)
}
}
Compiler error: Extension of protocol 'RawRepresentable' cannot have an inheritance clause
extension MyClass: MyProtocol {
// Conform to new protocol
}
extension MyProtocol {
// Default implementations for MyProtocol
}
protocol AnyRawRepresentable {
var anyRawValue: Any { get }
}
extension RawRepresentable: AnyRawRepresentable {
var anyRawValue: Any {
return rawValue
}
}
RawRepresentable
的类型,请使用此默认实现使该类型也符合
AnyRawRepresentable
。”
AnyRawRepresentable
不会有关联的类型要求,但仍然可以检索
rawValue
作为
Any
.在我们的代码中,然后:
if let anyRawEnum = theEnum as? AnyRawRepresentable { // Able to cast to
let anyRawValue = anyRawEnum.anyRawValue // anyRawValue is of type Any
switch anyRawValue {
case let s as String:
return s
case let csc as CustomStringConvertible:
return csc.description
default:
return nil
}
}
Mirror
的回复。在
RawRepresentable
枚举不包含其
rawValue
.至于选项 #2 和 #3,它们仍然在 Swift future 版本的可能性范围内。它们已在 Swift 邮件列表和
Generics Manifesto 中提及。由 Swift 团队的 Doug Gregor 撰写的文档。
Any
其中有关联类型或允许使用如下语法:
anyEnum as? Any<RawRepresentable where .RawValue == String>
关于swift - 从泛型函数中的枚举获取 rawValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31607629/
我有这个代码: enum Enum: String { case A = "A" } let s: String? = Enum(rawValue: "A") 当然,它不会编译。通常,我会这样
2015 年 8 月 28 日更新: 这将在 Swift 2 中解决 见 Twitter response from Swift compiler developer 2015 年 10 月 23 日
我正在评估 Multi-Tracker 示例,我想在条形码检测器可用后获取 RawValue。 一旦获得有效的 RawValue 并在其他地方使用该值,我想关闭 Tracker。 关于以下项目的任何建
我正在尝试Parcelize 一个数据类。它包含一个参数: var tokenType: Any? = null 对于这个变量,编译器在编译时提示: Type is not directly supp
考虑以下代码,我在其中声明了一个带有子枚举的 enum。 enum LocalizeKey { case message(Messages) case buttons(Buttons) enum Bu
我创建了一个非常简单的应用程序来限制您可以旋转 iPhone 的方向。在 ViewController 中,我重写方法 supportedInterfaceOrientations 如下: overr
嗯,老实说,我不喜欢在访问 enum 值时调用 rawValue。 我几乎一直都这样使用 enum,我认为调用 .rawValue 会降低我的代码的“可读性”: enum FontSize: CGFl
我有一个 Any? 类型的变量。我完全知道那个变量是 enum:String 的类型。我如何获得 rawValue 之类的东西: var somevar: Any? = someValue (some
我正在 Swift 中试验自定义运算符 (试验。我不需要讲授自定义运算符为什么不好) 我想,嗯,EnumType(rawValue:) 有点长.也许我可以找接线员解决这个问题?所以我写道: infix
我想到的一种方法是制定其他 Enum 必须遵守的协议(protocol)。 protocol StringRepresentable { var rawValue: String { get
今天我尝试在 Playground 中使用 OptionSet 进行一些操作,我注意到了这种模式 struct Activities: OptionSet { let rawValue:
我有以下枚举: enum Difficulty: Int { case Opt1 = 1, Opt2 = 2, Opt3 = 3 } 当我尝试像这样将它用作 Int 时:MyClass.
我正在使用 Xcode 6 的 playground 在 Swift 中尝试枚举: enum Rank: String { case One = "One", Two="Two" in
我想用一个嵌套枚举替换我的全局字符串常量,用于访问数据库中的列。 结构如下: enum DatabaseKeys { enum User: String { case Tabl
我有一个混合项目,遇到了一个有趣的问题。有一个枚举,在 obj-c 中定义 typedef NS_ENUM (NSUInteger, ABCCategory) { ABCCategoryFirst
我正在尝试在下面的结构中设置 var VendorIDDeviceID 的 rawValue。 struct vendor: Codable { var VendorIDDeviceID: S
我是一名初学者 Swift 开发人员,正在将我的应用程序迁移到 swift 3,但我无法修复此错误消息。实例成员“rawValue”不能用于类型“MessageComposeResult”你知道我的代
考虑这个枚举(注意它的类型是Int) enum MyTestEnum : Int{ case one = 1 case eight = 8 case unknown
我有一个枚举: enum switch : String { case on = "powerOn" case off = "powerOff" var ja
我正在查看 Swift 编程语言,我遇到了一个问题,我无法区分它是否是 Lauguage 的问题(我使用的是 Xcode 6.1 版(6A1052c)): enum Rank: Int { c
我是一名优秀的程序员,十分优秀!