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.
我假设枚举不能以这种方式使用。我们必须使用原语。
4 个解决方案
#1
11
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,枚举命名为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; As mentioned above in the snippets, you can return an instance of the struct based on what is the value of the referred enum.
事实上,我不太确定是否需要让CustomStruct成为MyEnum的父级来实现你想要的东西;如上面的片段中所述,您可以根据引用的枚举的值返回结构的实例。
#2
7
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.
我不是在评论在这里使用枚举的选择,而只是解释为什么你得到了这个错误以及如何声明一个自定义对象作为父对象的枚举。
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:
我们在此代码段中可以看到一些重要的事情:
- 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...). But please note that in Swift 3, the LiteralConvertible protocols are now called ExpressibleByXLiteral after the Big Swift Rename.
- The requirement to implement
RawRepresentable
is covered implementing one of the Expressible protocols (init?(rawValue:)
will leverage the initializer we wrote to support literals). - Enums must also be Equatable , so you'll have to implement the equality operator for your
CustomStruct
base type.
像ONE和TWO这样的情况必须用Swift文字表示,检查这个Swift 2帖子以获取可用文字列表(int,string,array,dictionary等)。但请注意,在Swift 3中,LiteralConvertible协议现在在Big Swift Rename之后被称为ExpressibleByXLiteral。
实现RawRepresentable的要求包括实现一个Expressible协议(init?(rawValue :)将利用我们编写的支持文字的初始化程序)。
枚举也必须是Equatable,因此您必须为CustomStruct基类型实现相等运算符。
#3
2
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类型。
#4
2
Did you try conforming to RawRepresentable like the error is asking?
您是否尝试过符合RawRepresentable,就像错误要求一样?
Using JSON representation should work for variable1 and variable3. Some extra work may be required for variable2.
使用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) ?? ""
}
}
#1
11
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,枚举命名为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; As mentioned above in the snippets, you can return an instance of the struct based on what is the value of the referred enum.
事实上,我不太确定是否需要让CustomStruct成为MyEnum的父级来实现你想要的东西;如上面的片段中所述,您可以根据引用的枚举的值返回结构的实例。
#2
7
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.
我不是在评论在这里使用枚举的选择,而只是解释为什么你得到了这个错误以及如何声明一个自定义对象作为父对象的枚举。
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:
我们在此代码段中可以看到一些重要的事情:
- 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...). But please note that in Swift 3, the LiteralConvertible protocols are now called ExpressibleByXLiteral after the Big Swift Rename.
- The requirement to implement
RawRepresentable
is covered implementing one of the Expressible protocols (init?(rawValue:)
will leverage the initializer we wrote to support literals). - Enums must also be Equatable , so you'll have to implement the equality operator for your
CustomStruct
base type.
像ONE和TWO这样的情况必须用Swift文字表示,检查这个Swift 2帖子以获取可用文字列表(int,string,array,dictionary等)。但请注意,在Swift 3中,LiteralConvertible协议现在在Big Swift Rename之后被称为ExpressibleByXLiteral。
实现RawRepresentable的要求包括实现一个Expressible协议(init?(rawValue :)将利用我们编写的支持文字的初始化程序)。
枚举也必须是Equatable,因此您必须为CustomStruct基类型实现相等运算符。
#3
2
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类型。
#4
2
Did you try conforming to RawRepresentable like the error is asking?
您是否尝试过符合RawRepresentable,就像错误要求一样?
Using JSON representation should work for variable1 and variable3. Some extra work may be required for variable2.
使用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) ?? ""
}
}