Swift 3.0中结构的枚举



我正在尝试创建一个要初始化的结构的枚举:

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
}

我们可以在这个片段中看到一些重要的东西:

  1. 像ONE和TWO这样的情况必须可以用Swiftliteral来表示,请查看Swift 2的这篇文章,查看可用的literal列表(int、string、array、dictionary等)。但请注意,在Swift 3中,在Big Swift Rename之后,LiteralConvertible协议现在被称为ExpressibleByXLiteral
  2. 实现RawRepresentable的需求包括实现一个Expressible协议(init?(rawValue:)将利用我们编写的支持文字的初始值设定项)
  3. 枚举必须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"

相关内容

  • 没有找到相关文章

最新更新