我正在尝试创建一个要初始化的结构的枚举:
struct CustomStruct {
var variable1: String
var variable2: AnyClass
var variable3: Int
init (variable1: String, variable2: AnyClass, variable3: Int) {
self.variable1 = variable1
self.variable2 = variable2
self.variable3 = variable3
}
}
enum AllStructs: CustomStruct {
case getData
case addNewData
func getAPI() -> CustomStruct {
switch self {
case getData:
return CustomStruct(variable1:"data1", variable2: SomeObject.class, variable3: POST)
case addNewData:
// Same to same
default:
return nil
}
}
}
我得到以下错误:
类型AllStructs不符合协议"RawRepresentable">
我假设枚举不能以这种方式使用。我们必须使用基元。
应该是:
struct CustomStruct {
var apiUrl: String
var responseType: AnyObject
var httpType: Int
init (variable1: String, variable2: AnyObject, variable3: Int) {
self.apiUrl = variable1
self.responseType = variable2
self.httpType = variable3
}
}
enum MyEnum {
case getData
case addNewData
func getAPI() -> CustomStruct {
switch self {
case .getData:
return CustomStruct(variable1: "URL_TO_GET_DATA", variable2: 11 as AnyObject, variable3: 101)
case .addNewData:
return CustomStruct(variable1: "URL_TO_ADD_NEW_DATA", variable2: 12 as AnyObject, variable3: 102)
}
}
}
用法:
let data = MyEnum.getData
let myObject = data.getAPI()
// this should logs: "URL_TO_GET_DATA 11 101"
print(myObject.apiUrl, myObject.responseType, myObject.httpType)
请注意,根据命名约定,结构应命名为CustomStruct
,枚举应命名为MyEnum
。
事实上,我不太确定是否需要让CustomStruct
成为MyEnum
的父级,以实现您想要的目标;如上所述,您可以根据引用枚举的值返回结构的实例。
我不是在这里评论使用枚举的选择,而是解释为什么会出现这个错误,以及如何声明一个具有自定义对象作为父对象的枚举。
该错误向您显示了问题,CustomStruct
必须实现RawRepresentable
才能用作该枚举的基类。
下面是一个简化的例子,它向您展示了您需要做什么:
struct CustomStruct : ExpressibleByIntegerLiteral, Equatable {
var rawValue: Int = 0
init(integerLiteral value: Int){
self.rawValue = value
}
static func == (lhs: CustomStruct, rhs: CustomStruct) -> Bool {
return
lhs.rawValue == rhs.rawValue
}
}
enum AllStructs: CustomStruct {
case ONE = 1
case TWO = 2
}
我们可以在这个片段中看到一些重要的东西:
- 像ONE和TWO这样的情况必须可以用Swiftliteral来表示,请查看Swift 2的这篇文章,查看可用的literal列表(int、string、array、dictionary等)。但请注意,在Swift 3中,在Big Swift Rename之后,LiteralConvertible协议现在被称为ExpressibleByXLiteral
- 实现
RawRepresentable
的需求包括实现一个Expressible协议(init?(rawValue:)
将利用我们编写的支持文字的初始值设定项) - 枚举必须也Equatable,因此您必须为
CustomStruct
基类型实现相等运算符
您是否像错误所问的那样尝试遵守RawRepresentable?
使用JSON表示应该适用于variable1和variable3。变量2可能需要一些额外的工作。
struct CustomStruct: RawRepresentable {
var variable1: String
var variable2: AnyClass
var variable3: Int
init?(rawValue: String) {
guard let data = rawValue.data(using: .utf8) else {
return nil
}
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
return nil
}
self.variable1 = (json["variable1"] as? String) ?? ""
self.variable2 = (json["variable2"] as? AnyClass) ?? AnyClass()
self.variable3 = (json["variable3"] as? Int) ?? 0
}
var rawValue: String {
let json = ["variable1": self.variable1,
"variable2": self.variable2,
"variable3": self.variable3
]
guard let data = try? JSONSerialization.data(withJSONObject: json, options: []) else {
return ""
}
return String(data: data, encoding: .utf8) ?? ""
}
}
根据文档:
如果为每个枚举情况提供了一个值(称为"原始"值),则该值可以是字符串、字符或任何整数或浮点类型的值。
因此,是的,不能将结构类型设置为枚举的原始值。
在您的情况下,我建议使用string
作为枚举原始值,并使用一些字典将这些字符串映射到CUSTOM_STRUCT
类型。
enum MyEnum {
case getData
case addNewData
var variable1: String {
switch self {
case .getData: return "data1"
case .addNewData: return "data2"
}
}
var variable2: Int {
switch self {
case .getData: return 1
case .addNewData: return 2
}
}
// ....
}
用法:
let data = MyEnum.getData
print (data.variable1) // "data1"