You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Scala 2.13中用宏生成全新单例字面量类型

解决Scala 2.13宏生成随机Int单例类型的问题

问题分析

你当前的宏仅生成了普通Int字面量,编译器会将其类型推断为Int,而非具体数值的单例类型(比如42.type)。要实现每次调用宏返回带独特单例类型的Int值,需要在宏中显式构造带有单例类型标注的语法树。

解决方案代码

修改宏实现,通过Typed节点为字面量指定对应的单例类型:

import scala.reflect.macros.blackbox
import scala.language.experimental.macros

def randomSingletonInt: Int = macro randomImpl

def randomImpl(c: blackbox.Context): c.Tree = {
  import c.universe._
  // 生成随机Int值,可按需替换其他随机逻辑
  val number = scala.util.Random.nextInt()
  // 构造字面量常量树
  val literal = Literal(Constant(number))
  // 构造对应数值的单例类型(如42.type)
  val singletonType = SingleType(ThisType(typeOf[Int].typeSymbol), literal)
  // 为字面量标记单例类型
  Typed(literal, singletonType)
}

验证效果

调用宏时,每个变量的类型都会是具体数值的单例类型:

val a = randomSingletonInt // a: 42 = 42
val b = randomSingletonInt // b: -112 = -112

适配隐式解析场景

你的隐式解析需求可以正常工作,生成的单例类型值会被编译器识别为对应类型的隐式实例:

class CustomType[K <: Int & Singleton]()

def randomTag[K <: Int & Singleton](implicit tag: K): CustomType[K] = new CustomType[K]

// 生成隐式单例Int值
implicit val a = randomSingletonInt
// 编译器自动推断K为a的单例类型(如42)
val tagged = randomTag // tagged: CustomType[42] = CustomType@...

补充说明

  • 随机值生成:示例用scala.util.Random.nextInt()替代了freshName().hashCode,前者能生成范围更均匀的随机Int值,可根据需求调整。
  • 单例类型构造:SingleType用于构造X.type形式的单例类型,这里以Int伴生对象为基础,结合字面量生成具体的单例类型。

内容的提问来源于stack exchange,提问作者LIshy2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:54:58