作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否可以使用镜像甚至宏来区分 Scala-3 枚举和密封特征?
transparent inline def isScalaEnum[A]: Boolean = ${ isScalaEnumImpl[A] }
private def isScalaEnumImpl[A: Type](using q: Quotes): Expr[Boolean] = ???
比如上面的宏是怎么实现的?
sealed trait T
case class A(x: Int) extends T
case class B(x: String) extends T
enum Color(val rgb: Int):
case Red extends Color(1)
case Green extends Color(2)
isScalaEnum[T] should be false
isScalaEnum[Color] should be true
最佳答案
你可以用 <:<
来做和 NotGiven
:
<:< reflect.Enum
用于检查您的类型是否是 scala.reflect.Enum
的子类(仅适用于 Scala 3 enum
s)NotGiven
用于翻译缺少 <:<
-证据变成false
实现方式如下:
import scala.util.NotGiven
case class IsEnum[X](value: Boolean)
given isEnum[X](using X <:< reflect.Enum): IsEnum[X] = IsEnum(true)
given isNotEnum[X](using NotGiven[X <:< reflect.Enum]): IsEnum[X] = IsEnum(false)
inline def isScalaEnum[X](using inline ev: IsEnum[X]): Boolean = ev.value
使用方法如下:
enum Foo:
case Bar
sealed trait NotFoo
@main def demo(): Unit =
println(isScalaEnum[Foo]) // true
println(isScalaEnum[NotFoo]) // false
如果您想在编译时获得更精确的类型信息,只需透明地内联所有内容即可:
import scala.util.NotGiven
case class IsEnum[X](value: Boolean)
transparent inline given isEnum[X](using X <:< reflect.Enum): IsEnum[X] =
IsEnum(true)
transparent inline given isNotEnum[X](using NotGiven[X <:< reflect.Enum]): IsEnum[X] =
IsEnum(false)
transparent inline def isScalaEnum[X](using inline ev: IsEnum[X]): ev.value.type =
ev.value
然后它的行为类似于您在自己的答案中提到的测试用例,带有 Null
和 Nothing
是值得注意的异常(exception):
enum Foo:
case Bar
enum FooS(x:String):
case Bar extends FooS("str")
sealed trait NotFoo
inline val a: true = isScalaEnum[Foo]
inline val b: true = isScalaEnum[Foo.Bar.type]
inline val c: true = isScalaEnum[FooS]
inline val d: true = isScalaEnum[FooS.Bar.type]
inline val e: false = isScalaEnum[NotFoo]
inline val f: false = isScalaEnum[Int]
inline val g: false = isScalaEnum[String]
inline val x: true = isScalaEnum[Null]
inline val y: true = isScalaEnum[Nothing]
关于scala - 区分 Scala-3 枚举和密封特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70009589/
我是一名优秀的程序员,十分优秀!