如何将不同的枚举类型传递给同一个变量,稍后识别其类型并使用其原始值来执行某些操作?
我有两个类型为String的枚举Menu1
和Menu2
。我喜欢将一系列枚举传递给另一个显示子菜单的类。我喜欢将枚举传递给同一个变量,因为我将来可能会添加另一个菜单。
答案 0 :(得分:2)
要应用抽象,您可以使用 protocol
,如下所示:
protocol Menu {}
enum Menu1: String, Menu {
case option1 = "Option 01 From Menu 01"
case option2 = "Option 02 From Menu 01"
case option3 = "Option 03 From Menu 01"
case option4 = "Option 04 From Menu 01"
case option5 = "Option 05 From Menu 01"
}
enum Menu2: String, Menu {
case option1 = "Option 01 From Menu 02"
case option2 = "Option 02 From Menu 02"
case option3 = "Option 03 From Menu 02"
case option4 = "Option 04 From Menu 02"
case option5 = "Option 05 From Menu 02"
}
通过实现这一点,您可以声明Menu
类型的数组,其中包含两个枚举:
let myMenu1Array: [Menu1] = [.option1, .option2, .option5]
let myMenu2Array: [Menu2] = [.option1, .option3, .option4]
例如,将参数作为Menu
的数组的函数应该起作用:
func handleMenu(_ menuArray: [Menu]) {
if let menu1Array = menuArray as? [Menu1] {
print("Menu 1 Detected!")
// you could iterate through it for instance...
for option in menu1Array {
print(option.rawValue)
}
return
}
if let menu2Array = menuArray as? [Menu2] {
print("Menu 2 Detected!")
// you could iterate through it for instance...
for option in menu2Array {
print(option.rawValue)
}
return
}
}
输出结果为:
handleMenu(myMenu1Array)
/*
Menu 1 Detected!
Option 01 From Menu 01
Option 02 From Menu 01
Option 05 From Menu 01
*/
handleMenu(myMenu2Array)
/*
Menu 2 Detected!
Option 01 From Menu 02
Option 03 From Menu 02
Option 04 From Menu 02
*/
因此,如果某个类中的属性应该代表一个菜单,则可以将其声明为Menu
的类型:
class MyClass {
...
var menu: Menu?
...
}
答案 1 :(得分:1)
您可以声明一个协议,两个枚举应该符合。 现在接受确认协议的函数参数。或者,您可以使用泛型。
答案 2 :(得分:1)
您需要一种方法来连接两个枚举,这可能是一个常见的Menu
协议。你将面临的问题是传递Menu
对象所涉及的类型擦除。添加新的菜单类型太容易了,而不是在代码中的任何地方检查它。
我建议使用一个小型重构器,将每个重构器包装到另一个枚举器中,由一个共同的结构管理。
enum Menu1: String {
case option1 = "Option 01 From Menu 01"
case option2 = "Option 02 From Menu 01"
case option3 = "Option 03 From Menu 01"
case option4 = "Option 04 From Menu 01"
case option5 = "Option 05 From Menu 01"
}
enum Menu2: String {
case option1 = "Option 01 From Menu 02"
case option2 = "Option 02 From Menu 02"
case option3 = "Option 03 From Menu 02"
case option4 = "Option 04 From Menu 02"
case option5 = "Option 05 From Menu 02"
}
struct Menu
{
enum MenuType
{
case one (Menu1)
case two (Menu2)
}
let type: MenuType
}
func handle(menu: Menu)
{
switch menu.type
{
case .one(let data): print (data.rawValue)
case .two(let data): print (data.rawValue)
}
}
let menu = Menu(type: .one(Menu1.option1))
handle(menu: menu)
这种方法的主要优点:
答案 3 :(得分:0)
我们可以使用协议发送任何枚举对象,无需输入 强制转换对象以访问 rawValue。我们可以通过不同类型的 枚举并读取值。
protocol AttributeKeyProtocol {
var value: String { get }
}
struct AttributeData {
let key: AttributeKeyProtocol
let value: String
init(key: AttributeKeyProtocol, value: String) {
self.key = key
self.value = value
}
}
enum MyClasses: AttributeKeyProtocol {
var value: String {
switch self {
case .one(.logo):
return"logo"
default:
return "all"
}
}
case one(MyComputerClasses)
case two
enum MyComputerClasses: String, AttributeKeyProtocol {
case logo
case pascal
var value: String {
return self.rawValue
}
}
}
MyClasses implementing 'AttributeKeyProtocol'
enum MyCourses: String, AttributeKeyProtocol {
case three = "psd_ssj_sdoj"
case four
var value: String {
return self.rawValue
}
}
class NewSDK {
func track(name: String, type: String, attributes: [AttributeData]?) {
print("attributes: \(attributes?.first?.key.value)")
print("attributes: \(attributes?.last?.key.value)")
}
}
NewSDK().track(name: "sfd", type: "dsfd", attributes: [.init(key: MyClasses.one(.logo) , value: "sdfd"),
.init(key: MyCourses.three, value: "sfdfsd")])