使Swift(2.1)枚举符合任何对象

使Swift(2.1)枚举符合任何对象,swift,enums,swift2.1,Swift,Enums,Swift2.1,我有一些类型的字典: public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject] public typealias RESTRequestDictionary = [RESTRequestDictionaryKey : AnyObject] 我使用enum是因为我希望字典的键只能是enum中的一种情况: public enum RESTPostDictionaryKey : String { cas

我有一些类型的字典:

public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
public typealias RESTRequestDictionary = [RESTRequestDictionaryKey : AnyObject]
我使用enum是因为我希望字典的键只能是enum中的一种情况:

public enum RESTPostDictionaryKey : String
{
    case Requests = "requests"
}
以及:

因为从技术上讲,我的枚举是一种字符串类型,所以我认为编译器获取它的底层字符串值并使用它是没有问题的。但我得到了警告:

无法将类型“Array”的值aka…分配给类型“AnyObject”

在以下功能中:

class public func postDictionaryWithRequestDictionaries(requestDictionaries: Array<RESTRequestDictionary>) -> RESTPostDictionary
{
    var postDictionary = RESTPostDictionary()

    postDictionary[.Requests] = requestDictionaries

    return postDictionary
}
有没有任何方法可以告诉编译器通过使用协议或其他方式获取其字符串,而不必依赖脏的和非Swift的.rawValue

还是我做错了什么?

这是不对的:

public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
你的意思是:

public typealias RESTPostDictionary = [String : AnyObject]
枚举不是字符串。但它是您打算用作键的字符串

使用枚举大小写作为键时,取其原始值:

因此,例如,这是合法的:

enum Keys : String {
    case Key1 = "hey"
    case Key2 = "ho"
    case Key3 = "hey nonny no"
}

var d = [String:AnyObject]()
d[Keys.Key1.rawValue] = 1
d[Keys.Key2.rawValue] = 2

为什么不简单地使用enum作为键

import Foundation

enum E:String, CustomStringConvertible {
    var description: String { return self.rawValue }
    case A = "text A"
    case B = "B text"
    case C = "neither A nor B but C"
}

var dict: Dictionary<E, Any> = [:]
dict[E.A] = "alfa"
dict[E.B] = 1
dict[E.C] = NSDate()

dump(dict)

/*
▿ 3 key/value pairs
▿ [0]: (2 elements)
- .0: E.C
- .1: Nov 8, 2015, 11:01 AM
▿ [1]: (2 elements)
- .0: E.A
- .1: alfa
▿ [2]: (2 elements)
- .0: E.B
- .1: 1
*/

print(dict)
// [neither A nor B but C: 2015-11-08 10:02:47 +0000, text A: "alfa", B text: 1]
可以转换为JSON的对象必须具有以下特性 特性:

顶级对象是NSArray或NSDictionary

所有对象都是NSString、NSNumber、NSArray、, NSDictionary,或NSNull

所有字典键都是NSString的实例

数字不是NaN或无穷大


查看完整答案/下载源代码

我理解您的观点,但我希望我的RESTPostDictionary只使用RESTPostDictionaryKey枚举中的键。我的观点是,这应该是可行的,因为从技术上讲,枚举是一种字符串类型,它符合任何对象?实际上,你不理解我的观点,因为我的观点是,枚举从技术上讲不是一个字符串。从技术上讲,它是一个枚举,这是一个非常不同的动物。好吧,除了rawValue属性之外,没有其他方法告诉编译器?我已经将枚举更改回每个键都有静态常量的结构。谢谢你的帮助虽然我在任何地方都没有试过你,但我很感谢你的帮助,并对我的想法不起作用感到失望。为什么你要限制字典只包含对象?如果您不需要只使用对象,您可以将AnyObject更改为AnyI不知道Any,但是当我使用Any时,我就不能将字典用作字典,例如,我使用方法NSJSONSerialization.dataWithJSONObjectpostDictionary,选项:[]得到的错误是“RESTPostDictionary”不符合预期的类型“AnyObject”哦,是的,如果你必须使用objects,Obj-C不能处理其他任何东西,但是编译器告诉我,当将该类型与NSJSONSerialization Classification一起使用时,它不符合AnyObject。有没有一种方法可以编写一个扩展,使我的自定义类型[StringBasedEnum:AnyObject]符合AnyObject的Swift类型?现在我看到Matts的答案了。所以,你什么都知道。。。enum是enum,不是字符串。即使NSDictionary中的键是NSString,也可以将其与枚举进行比较。带有关联字符串值的枚举的工作方式类似于有限的字符串值集。我使用符合Streamable的枚举值作为我的JSON“staff”。JSON的序列化既简单又快速,我使用自己的解析器直接映射到JSON兼容的枚举。一切都取决于你的需要,网上有很多例子
enum Keys : String {
    case Key1 = "hey"
    case Key2 = "ho"
    case Key3 = "hey nonny no"
}

var d = [String:AnyObject]()
d[Keys.Key1.rawValue] = 1
d[Keys.Key2.rawValue] = 2
import Foundation

enum E:String, CustomStringConvertible {
    var description: String { return self.rawValue }
    case A = "text A"
    case B = "B text"
    case C = "neither A nor B but C"
}

var dict: Dictionary<E, Any> = [:]
dict[E.A] = "alfa"
dict[E.B] = 1
dict[E.C] = NSDate()

dump(dict)

/*
▿ 3 key/value pairs
▿ [0]: (2 elements)
- .0: E.C
- .1: Nov 8, 2015, 11:01 AM
▿ [1]: (2 elements)
- .0: E.A
- .1: alfa
▿ [2]: (2 elements)
- .0: E.B
- .1: 1
*/

print(dict)
// [neither A nor B but C: 2015-11-08 10:02:47 +0000, text A: "alfa", B text: 1]
import Foundation

enum E:String, CustomStringConvertible {
    var description: String { return self.rawValue }
    case A = "key A"
    case B = "key B"
    case C = "key C"
}

var dict: Dictionary<NSString, AnyObject> = [:]

dict[E.A.description] = "alfa"
dict[E.B.description] = [1,2,3]
dict[E.C.description] = NSDate()

dict is AnyObject // false
let nsdict = dict as NSDictionary
nsdict is AnyObject // true
print(nsdict)

/*

{
    "key A" = alfa;
    "key B" =     (
        1,
        2,
        3
    );
    "key C" = "2015-11-09 23:13:31 +0000";
}
*/
class Box<T> {
  let value: T
  init(value: T) {
    self.value = value
  }
}
NSNotificationCenter.defaultCenter().postNotificationName("foo", object: Box(value: YourOwnStruct())) // OK
extension YourOwnStruct: AnyObjectConvertible {}

NSNotificationCenter.defaultCenter().postNotificationName("foo", object: YourOwnStruct()) // OK let value = notification.object as? YourOwnStruct