【问题标题】:Constrain generic type by swift enum通过 swift 枚举约束泛型类型
【发布时间】:2020-07-10 14:00:22
【问题描述】:

我想通过选择不同的枚举案例来限制 Swift 中的泛型类型。

下面是一个代码示例:

enum Test {
  case T1
  case T2
}

enum T1 {
  case one
  case two
}

enum T2 {
  case three
  case four
}


indirect enum Foo<T> {
  case empty
  case cons(T, Foo<T>)
}

let x: Foo<T1> = .cons(.one, .empty)

我有一个第一个枚举,其中包含 T1 和 T2 的两个案例。 我试图将 Foo Enum 中的类型 T 限制为具有可用类型的集合,在我的示例中为 T1 和 T2 。 当我声明x 时,允许的类型是T1 或T2 包含在Test 中,而不是其他类型。 因此,只能允许 Enum Test 中的类型。

我的问题:是否可以使用我的 Enum 来约束泛型类型?如果是,如何? 不然怎么办?

【问题讨论】:

  • 重申我认为您要问的内容...是否可以有一个泛型类型可以是 A 或 B 或 C 类型,但不能是其他类型。答案是否定的。您可以约束到协议或类,或基于协议的关联类型
  • 感谢您的回答,您理解我的问题。我可以用协议做这种事情吗?
  • “这种东西”是什么意思?如果你的意思是,你能限制一个协议,那么是的 - 这正是我在评论中所说的。也许我误解了你在问什么......
  • 对不起,我必须更准确。我想知道我是否可以通过协议限制我想要的方式(所以 T1 和 T2)。想象一下我可以有10种不同的类型来约束,我该怎么做?

标签: swift generics enums


【解决方案1】:

方法一

根据 cmets 的说法,我认为这就是您要完成的任务:

protocol MyEnums {}

enum T1: MyEnums { case one, two }
enum T2: MyEnums { case one, two }
enum T3 { case one, two }

let foo: [MyEnums] = [T1.one, T1.two, T2.one, T2.two]

数组只能包含符合MyEnums 协议的对象。
请注意枚举T3 不能存储在foo 中,因为它不符合MyEnums 协议。


方法二

这里还有一点。你实际上可以按照你的要求去做:

protocol MyEnums {}
enum T1: MyEnums { case one, two }
enum T2: MyEnums { case one, two }
enum T3 { case one, two }
indirect enum Foo<T: MyEnums> {
  case empty
  case cons(T, Foo<T>)
}

请注意,泛型是&lt;T: MyEnums&gt;。
此代码将完全按照您的意愿执行。它可以存储符合MyEnums 协议的枚举。因此,您可以存储符合MyEnums 的枚举 T1 和 T2,但不能存储 T3,因为它不符合。

所以你将能够做到这一点:

let x: Foo = .cons(T1.one, .cons(T1.two, .empty))

但是第二种方法不允许这样做:

let x: Foo = .cons(T1.one, .cons(T2.one, .empty))

我会尝试看看我们是否可以做到这一点..


方法3

我明白了!!这正是您所要求的:

protocol MyEnums {}
protocol MyEnums1: MyEnums {}

enum T1: MyEnums1 { case one, two }
enum T2: MyEnums1 { case one, two }
enum T3 { case one, two }

indirect enum Foo<T: MyEnums> {
  case empty
  case cons(MyEnums1, Foo<T>)
}

let x: Foo<T1> = .cons(T1.one, .cons(T2.one, .empty))
print(x)

它需要2个协议,但我最终修复了方法2。记住,你只能放入符合MyEnums1的对象,所以T3不是一个选项。完美!

这是一个非常酷的问题。

【讨论】:

  • 感谢您的回答!这正是我想要的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多