【问题标题】:Enum of structs in Swift 3.0Swift 3.0 中的结构枚举
【发布时间】:2017-06-14 19:05:03
【问题描述】:

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

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'

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

【问题讨论】:

  • 您没有任何名为apiUrlresponseTypehttpType 的属性。请先在操场上检查您的代码错误,然后编辑您的问题。您的init 方法也有两个variable3,我想进行编辑,但最好您自己做,这样您就知道自己做错了什么
  • MNOX_MAPPINGS 是什么你想在你的getAPI 函数中做什么?
  • 抱歉问题格式不正确..已更正..
  • 请告诉我可以做些什么来纠正我的问题..
  • @Siddharth 正如我在回答中提到的,我认为您应该注意命名约定...

标签: ios swift enums rawrepresentable


【解决方案1】:

根据documentation

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

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

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

【讨论】:

  • 请注意,您引用的文档有点误导 - 您可以拥有可由字符串、字符、整数或浮点表示的类型的原始值 literal (您可以将此行为添加到您自己的类型中)。虽然我不知道 OP 如何为他的CUSTOM_STRUCT 有效地做到这一点,甚至不知道他为什么要首先这样做。
  • @Hamish 可能只能通过解析字符串文字。这将是一个糟糕的解决方案。
  • @Sulthan 是的——这就是我所说的“有效” :) 无论如何,看起来 OP 不希望 ALL_STRUCTS 具有 CUSTOM_STRUCT 类型的原始值——他只是想要一个方法。
【解决方案2】:

应该是:

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

【讨论】:

【解决方案3】:

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

错误说明了问题所在,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
}

我们可以在这个 sn-p 中看到一些重要的事情:

  1. 像 ONE 和 TWO 这样的情况 必须 可以用 Swift literal 表示,检查this Swift 2 post 以获取可用的文字列表(int、string、array、dictionary、等等...)。但请注意,在 Swift 3 中,LiteralConvertible 协议现在在 Big Swift Rename 之后称为 ExpressibleByXLiteral
  2. 实现RawRepresentable 的要求包括实现Expressible 协议之一(init?(rawValue:) 将利用我们编写的初始化程序来支持文字)。
  3. 枚举必须也是 Equatable ,因此您必须为您的 CustomStruct 基本类型实现相等运算符。

【讨论】:

  • 其实CUSTOM_STRUCT不需要符合RawRepresentable——只要一个合适的ExpressibleByXLiteral协议和Equatable
【解决方案4】:

您是否尝试按照错误要求遵守 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) ?? ""
    }
}

【讨论】:

  • 谢谢,我也会尝试这个答案并返回
猜你喜欢
  • 2021-06-05
  • 2017-05-12
  • 1970-01-01
  • 2016-11-29
  • 2015-09-23
  • 2020-08-10
  • 2019-02-07
相关资源
最近更新 更多