限制通用的 Kotlin 枚举到特定类型

huangapple go评论57阅读模式
英文:

Restrict Generic Kotlin Enum to certain type

问题

我想在编译时强制参数的类型为实现接口的枚举

```kotlin
interface MyInterface {
    val value: String
}

enum class WrongTypeEnum {
    WrongEnum1,
    WrongEnum2,
}

enum class CorrectTypeEnum(override val value: String) : MyInterface {
    CorrectEnum1("value1"),
    CorrectEnum2("value2");
}

如果我编写一个泛型函数,事情会正常工作:

fun <T : Enum<out MyInterface>> myFunction(param: T) {...}

myFunction(CorrectTypeEnum.CorrectEnum1) // 编译成功
myFunction(WrongTypeEnum.WrongEnum1)  // 正确显示编译错误

问题是如果是一个泛型类,情况就不同:

class MyClass<T : Enum<out MyInterface>>
// 上述代码会显示以下编译时错误:
//    类型参数不在其边界内。
//    期望: Enum<out MyInterface>
//    找到: MyInterface

所以,问题是:我做错了什么,如何让 MyClass 能够接受也实现了 MyInterface 接口的枚举类?

英文:

I would like to enforce, at compile time, the type of a parameter to an Enum that also implements an interface:

interface MyInterface {
    val value: String
}

enum class WrongTypeEnum {
    WrongEnum1,
    WrongEnum2,
}

enum class CorrectTypeEnum(override val value: String) : MyInterface {
    CorrectEnum1(&quot;value1&quot;),
    CorrectEnum2(&quot;value2&quot;);
}

If I write a generic function, things work correctly:

fun &lt;T : Enum&lt;out MyInterface&gt;&gt; myFunction(param: T) {...}

myFunction(CorrectTypeEnum.TestEnum1) // compiles successfully
myFunction(WrongTypeEnum.WrongEnum1)  // correctly shows compile error

Problem is that things don't work the same way if it's a generic class:

class MyClass&lt;T : Enum&lt;out MyInterface&gt;&gt;
// The above line shows the following compile time error:
//    Type argument is not within its bounds.
//    Expected: Enum&lt;out MyInterface&gt;
//    Found: MyInterface

So, question is: what am I doing wrong and how can I make it that MyClass can by typed to enum classes that also implement MyInterface?

答案1

得分: 3

是的,类参数的语法稍微复杂一些:

class MyClass<T> where T: Enum<T>, T: MyInterface {}

同样的语法也适用于函数:

fun <T> myFunction(param: T) where T : Enum<T>, T: MyInterface {}
英文:

Yes, the syntax for class parameters is a little more convoluted:

class MyClass&lt;T&gt; where T: Enum&lt;T&gt;, T: MyInterface {}

The same syntax does also work for functions:

fun &lt;T&gt; myFunction(param: T) where T : Enum&lt;T&gt;, T: MyInterface {}

huangapple
  • 本文由 发表于 2023年6月15日 16:33:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76480605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定