简体   繁体   English

Swift 3.0中的结构枚举

[英]Enum of structs in Swift 3.0

I am trying to create an enum of a struct that I would like to initialize: 我正在尝试创建一个我想初始化的结构的枚举:

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

I get the following errors: 我收到以下错误:

Type AllStructs does not conform to protocol 'RawRepresentable' 类型AllStructs不符合协议“ RawRepresentable”

I am assuming that enums cannot be used this way. 我假设枚举不能以这种方式使用。 We must use primitives. 我们必须使用原语。

It should be: 它应该是:

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

Usage: 用法:

let data = MyEnum.getData
let myObject = data.getAPI()

// this should logs: "URL_TO_GET_DATA 11 101"
print(myObject.apiUrl, myObject.responseType, myObject.httpType)

Note that upon Naming Conventions, struct should named as CustomStruct and enum named as MyEnum . 请注意,根据命名约定,struct应该命名为CustomStruct而enum命名为MyEnum

In fact, I'm not pretty sure of the need of letting CustomStruct to be the parent of MyEnum to achieve what are you trying to; 实际上,我不太确定是否需要让CustomStruct成为MyEnum的父MyEnum来实现您想要的目标。 As mentioned above in the snippets, you can return an instance of the struct based on what is the value of the referred enum. 如上面的代码片段所述,您可以根据所引用枚举的值返回该结构的实例。

I'm not commenting on the choice to use an enum here, but just explaining why you got that error and how to declare an enum that has a custom object as parent . 我没有在这里评论使用枚举的选择,而只是在解释为什么会出现此错误以及如何声明具有自定义对象的枚举作为parent

The error shows you the problem, CustomStruct must implement RawRepresentable to be used as base class of that enum. 该错误向您显示了问题, CustomStruct必须实现RawRepresentable才能用作该枚举的基类。

Here is a simplified example that shows you what you need to do: 这是一个简化的示例,向您显示您需要做什么:

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
}

A few important things that we can see in this snippet: 我们可以在此片段中看到一些重要的事情:

  1. The cases like ONE and TWO must be representable with a Swift literal , check this Swift 2 post for a list of available literals (int,string,array,dictionary,etc...). 诸如ONE和TWO之类的情况必须使用Swift 文字表示,请查看此Swift 2文章以获取可用文字列表(int,string,array,dictionary等)。 But please note that in Swift 3, the LiteralConvertible protocols are now called ExpressibleByXLiteral after the Big Swift Rename. 但是请注意,在Swift 3中,在Big Swift重命名之后, LiteralConvertible协议现在称为ExpressibleByXLiteral
  2. The requirement to implement RawRepresentable is covered implementing one of the Expressible protocols ( init?(rawValue:) will leverage the initializer we wrote to support literals). 实现RawRepresentable的要求涵盖了实现Expressible协议之一的要求( init?(rawValue:)将利用我们编写的初始化程序来支持文字)。
  3. Enums must also be Equatable , so you'll have to implement the equality operator for your CustomStruct base type. 枚举也必须Equatable ,因此您必须为CustomStruct基类型实现相等运算符。

Did you try conforming to RawRepresentable like the error is asking? 您是否按照错误要求尝试符合RawRepresentable?

Using JSON representation should work for variable1 and variable3. 使用JSON表示法应该适用于variable1和variable3。 Some extra work may be required for variable2. 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) ?? ""
    }
}

According to the documentation : 根据文档

If a value (known as a “raw” value) is provided for each enumeration case, the value can be a string, a character, or a value of any integer or floating-point type. 如果为每种枚举情况提供了一个值(称为“原始”值),则该值可以是字符串,字符或任何整数或浮点类型的值。

So yes, you cannot set a struct type to be enum's raw value. 因此,是的,您不能将结构类型设置为枚举的原始值。

In your case I would suggest using string as the enum raw value and some dictionary mapping these strings to CUSTOM_STRUCT type. 在您的情况下,我建议使用string作为枚举原始值,并建议使用一些字典将这些字符串映射为CUSTOM_STRUCT类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM