简体   繁体   English

Swift:在编译时将枚举值映射到类型

[英]Swift: map enum values to types at compile time

I've got an enum in a library target. 我在库目标中有一个枚举。 Like this: 像这样:

enum SomeEnum {
  case EnumValue1
  case EnumValue2
  case EnumValue3
}

I've got some structs in my app. 我的应用程序中有一些结构。 Like this: 像这样:

struct Struct1 {...}
struct Struct2 {...}
struct Struct3 {...}

My aim to map this structs to enum values in my app at compile time. 我的目标是在编译时将此结构映射到我的应用程序中的枚举值。 Something like this: 像这样:

extension SomeEnum {
  case EnumValue1(Struct1)
  case EnumValue2(Struct2)
  case EnumValue3(Struct2)
}

But apparently I can't add associated values in an extension. 但是显然我不能在扩展中添加关联的值。

Original enum in a library shouldn't know anything about my app structs. 库中的原始枚举对我的应用程序结构一无所知。 I'd like to perform this mapping on the app side. 我想在应用程序端执行此映射。 So I can't modify my original enum. 因此,我无法修改原始枚举。 How can I achieve this? 我该如何实现?

EDIT: Sorry, I've missed a use case example. 编辑:抱歉,我错过了一个用例示例。 I want to create an object of corresponding struct type for each enum value: 我想为每个枚举值创建一个对应的结构类型的对象:

func createStruct<T>(type: T.Type) {
  return T()
}

Usage: 用法:

let enumValue = SomeEnum.EnumValue2
//here I should use an invented way of mapping enum value to struct:
let object = createStruct(enumValue.struct)

It's not possible. 这是不可能的。 Qute from here 这里出发

the raw-value type must conform to the Equatable protocol and one of the following literal-convertible protocols: IntegerLiteralConvertible for integer literals, FloatingPointLiteralConvertible for floating-point literals, StringLiteralConvertible for string literals that contain any number of characters, and ExtendedGraphemeClusterLiteralConvertible for string literals that contain only a single character. 原始值类型必须符合Equatable协议以及以下文字可转换协议之一:IntegerLiteralConvertible(用于整数文字),FloatingPointLiteralConvertible(用于浮点文字),StringLiteralConvertible(用于包含任意数量字符的字符串文字)和ExtendedGraphemeClusterLiteralConvertible(用于字符串文字)只能包含一个字符。

even if you try to realize Equatable protocol - it won't work. 即使您尝试实现Equatable协议-也无法使用。

struct Struct1 : Equatable {}

func ==(lhs: Struct1, rhs: Struct1) -> Bool {
    return true // some code here
}

enum SomeEnum {
    case EnumValue1 = Struct1
}

This code won't work. 此代码无效。 Maybe you should create some String that will match your struct. 也许您应该创建一些与您的结构匹配的String

UPD: You can use associated values like it's said in docs . UPD:您可以像在docs中那样使用关联的值。 And it will be during compilation not runtime. 而且它将在编译期间而不是运行时。

struct Struct1 {}
struct Struct2 {}
struct Struct3 {}

enum SomeEnum {
    case EnumValue1(Struct1)
    case EnumValue2(Struct2)
    case EnumValue3(Struct3)
}

You can do it with: 您可以执行以下操作:

extension SomeEnum {
    func getStruct() -> Any.Type {
        switch self {
        case .EnumValue1:
            return Struct1.self
        case .EnumValue2:
            return Struct2.self
        case .EnumValue3:
            return Struct3.self
        }
    }
}

let structType = SomeEnum.EnumValue1.getStruct()

But it seems useless because you do not know type of structType and have to use switch...case again to determine it. 但这似乎没用,因为您不知道structType类型,而必须再次使用switch...case来确定它。

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

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