Swift 3.0中结构的枚举

时间:2017-01-29 14:41:22

标签: ios swift enums rawrepresentable

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

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
        }
    }
}

我收到以下错误:

  

Type AllStructs不符合协议'RawRepresentable'

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

4 个答案:

答案 0 :(得分:13)

应该是:

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)

请注意,在命名约定时,struct应命名为CustomStruct,枚举命名为MyEnum

事实上,我并不十分确定是否需要让CustomStruct成为MyEnum的父母来实现您的目标;如上面的代码片段所示,您可以根据引用的枚举值返回结构的实例。

答案 1 :(得分:12)

我不是在评论在这里使用枚举的选择,而只是解释为什么会出现这个错误,如何声明一个自定义对象作为父的枚举。

错误显示问题,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 literal 表示,检查this Swift 2 post以获取可用文字列表(int,string,array,字典,等...)。但请注意,在Swift 3中, LiteralConvertible 协议现在在Big Swift Rename之后被称为 ExpressibleByXLiteral
  2. 实现RawRepresentable的要求包括实现一个Expressible协议(init?(rawValue:)将利用我们编写的支持文字的初始化程序)。
  3. 枚举必须也是 Equatable ,因此您必须为CustomStruct基类型实现等于运算符。

答案 2 :(得分:3)

您是否尝试过符合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) ?? ""
    }
}

答案 3 :(得分:2)

根据documentation

  

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

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

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