14

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

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”

我假设不能以这种方式使用枚举。我们必须使用原语。

4

4 回答 4

20

它应该是:

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来实现您想要的目标;正如上面在片段中提到的,您可以根据引用的枚举的值返回结构的实例。

于 2017-01-29T14:58:53.230 回答
14

我没有评论在这里使用枚举的选择,而只是解释为什么会出现该错误以及如何声明具有自定义对象的枚举作为 parent

该错误向您显示了问题,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 之类的情况必须可以用 Swift文字来表示,请查看这篇 Swift 2 帖子以获取可用文字(int、string、array、dictionary 等)的列表。但请注意,在 Swift 3 中,LiteralConvertible协议现在在 Big Swift Rename 之后称为ExpressibleByXLiteral 。
  2. 实现的要求RawRepresentable包括实现 Expressible 协议之一(init?(rawValue:)将利用我们编写的初始化程序来支持文字)。
  3. 枚举也必须是Equatable,因此您必须为您的CustomStruct基本类型实现相等运算符。
于 2017-01-29T15:11:18.617 回答
3

您是否尝试像错误要求的那样遵守 RawRepresentable?

使用 JSON 表示应该适用于变量 1 和变量 3。variable2 可能需要一些额外的工作。

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) ?? ""
    }
}
于 2017-01-29T15:16:27.867 回答
2

根据文档

如果为每个枚举情况提供了一个值(称为“原始”值),则该值可以是字符串、字符或任何整数或浮点类型的值。

所以是的,您不能将结构类型设置为枚举的原始值。

在您的情况下,我建议使用string枚举原始值和一些将这些字符串映射到CUSTOM_STRUCT类型的字典。

于 2017-01-29T14:53:11.950 回答