是否可以在内联方法或子句中发出动态生成的编译器错误消息?

问题描述 投票:0回答:1

通过方法上下文参数调用实例允许自定义错误消息,以声明方式使用 @implicitNotFound 注释参数,这需要一个literal字符串支持类型占位符

import scala.annotation.implicitNotFound
        
inline def singleInhabitantOf[A](using @implicitNotFound("The received type ${A} is not a singleton") voA: ValueOf[A]): A =
   voA.value
    
singleInhabitantOf[Option[Int]] // Compile error: The received type Option[Int] is not a singleton

如果使用

summonFrom
实现召唤,我们可以自定义错误消息,强制调用
error
方法,该方法也需要 literal 字符串,但 没有类型占位符支持

import scala.compiletime.{summonFrom, error}
        
inline def singleInhabitantOf2[A]: A = summonFrom {
    case voA: ValueOf[A] => voA.value
    case _ => error("The received type ${A} is not a singleton")    
}

singleInhabitantOf2[Option[Int]] // compiler error: The received type ${A} is not a singleton

除了使用宏之外,还有没有一种方法可以在主体中调用一个隐式实例(如

summonFrom
那样),该实例具有类型占位符支持,或者更好的是动态字符串插值?

scala inline compile-time scala-3
1个回答
0
投票

许多标准内联方法实际上是作为宏或编译器内部实现的。

shapeless3.typeable.Typeable[A].describe
但它不是内联的,所以不能在
error
中使用。

我在标准库中找不到这个,但你可以定义自己的小宏并在普通内联方法中随处使用它

// different file
import scala.quoted.{Quotes, Type, Expr}

inline def typeOf[A]: String = ${typeOfImpl[A]}
def typeOfImpl[A: Type](using Quotes): Expr[String] = Expr(Type.show[A])
import scala.compiletime.{summonFrom, error}

inline def singleInhabitantOf2[A]: A = summonFrom {
  case voA: ValueOf[A] => voA.value
  case _ => error("The received type " + typeOf[A] + " is not a singleton")
}
© www.soinside.com 2019 - 2024. All rights reserved.