使 Swift (2.1) 枚举符合 AnyObject
Make a Swift (2.1) enum conform to AnyObject
我有几本字典是这样的:
public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
public typealias RESTRequestDictionary = [RESTRequestDictionaryKey : AnyObject]
我使用枚举是因为我希望字典的键只是枚举中的一种情况:
public enum RESTPostDictionaryKey : String
{
case Requests = "requests"
}
并且:
public enum RESTRequestDictionaryKey : String
{
case RequestURI = "request_uri"
case HTTPMethod = "http_method"
case DataDictionary = "data_dictionary"
case RequestIdentifier = "request_identifier"
case ResponseFormats = "response_formats"
}
由于我的枚举在技术上是 String
类型,我原以为编译器获取其底层字符串值(符合 AnyObject
)并使用那。但我收到警告:
Cannot assign value of type ‘Array<RESTRequestDictionary>’ aka … to type 'AnyObject?’
在以下函数中:
class public func postDictionaryWithRequestDictionaries(requestDictionaries: Array<RESTRequestDictionary>) -> RESTPostDictionary
{
var postDictionary = RESTPostDictionary()
postDictionary[.Requests] = requestDictionaries
return postDictionary
}
有没有什么方法可以告诉编译器通过使用协议或其他东西获得它的 String
而不必依赖肮脏的和不像 Swift 的 .rawValue?
还是我做错了什么?
这是不正确的:
public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
你的意思是这样的:
public typealias RESTPostDictionary = [String : AnyObject]
枚举不是字符串。但它是您打算用作密钥的字符串。
使用枚举大小写作为key时,取其rawValue
:
postDictionary[RESTRequestDictionaryKey.Requests.rawValue] = requestDictionaries
因此,例如,这是合法的:
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]
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray,
NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
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
如果在该类型下实现 AnyObjectConvertible,您可以转换 struct/enum 目录。
extension YourOwnStruct: AnyObjectConvertible {}
NSNotificationCenter.defaultCenter().postNotificationName("foo", object: YourOwnStruct()) // OK let value = notification.object as? YourOwnStruct
查看来自 here
的完整 answer/download 来源
我有几本字典是这样的:
public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
public typealias RESTRequestDictionary = [RESTRequestDictionaryKey : AnyObject]
我使用枚举是因为我希望字典的键只是枚举中的一种情况:
public enum RESTPostDictionaryKey : String
{
case Requests = "requests"
}
并且:
public enum RESTRequestDictionaryKey : String
{
case RequestURI = "request_uri"
case HTTPMethod = "http_method"
case DataDictionary = "data_dictionary"
case RequestIdentifier = "request_identifier"
case ResponseFormats = "response_formats"
}
由于我的枚举在技术上是 String
类型,我原以为编译器获取其底层字符串值(符合 AnyObject
)并使用那。但我收到警告:
Cannot assign value of type ‘Array<RESTRequestDictionary>’ aka … to type 'AnyObject?’
在以下函数中:
class public func postDictionaryWithRequestDictionaries(requestDictionaries: Array<RESTRequestDictionary>) -> RESTPostDictionary
{
var postDictionary = RESTPostDictionary()
postDictionary[.Requests] = requestDictionaries
return postDictionary
}
有没有什么方法可以告诉编译器通过使用协议或其他东西获得它的 String
而不必依赖肮脏的和不像 Swift 的 .rawValue?
还是我做错了什么?
这是不正确的:
public typealias RESTPostDictionary = [RESTPostDictionaryKey : AnyObject]
你的意思是这样的:
public typealias RESTPostDictionary = [String : AnyObject]
枚举不是字符串。但它是您打算用作密钥的字符串。
使用枚举大小写作为key时,取其rawValue
:
postDictionary[RESTRequestDictionaryKey.Requests.rawValue] = requestDictionaries
因此,例如,这是合法的:
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]
An object that may be converted to JSON must have the following properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
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
如果在该类型下实现 AnyObjectConvertible,您可以转换 struct/enum 目录。
extension YourOwnStruct: AnyObjectConvertible {}
NSNotificationCenter.defaultCenter().postNotificationName("foo", object: YourOwnStruct()) // OK let value = notification.object as? YourOwnStruct
查看来自 here
的完整 answer/download 来源