gpt4 book ai didi

scala - 类型安全的生成器 : How to set compiler error message

转载 作者:行者123 更新时间:2023-12-01 10:02:55 25 4
gpt4 key购买 nike

我在类型安全的构建器模式中使用虚类型来确保方法只被调用一次,如以下代码示例所示

  sealed trait TBoolean
sealed trait TTrue extends TBoolean
sealed trait TFalse extends TBoolean

class Builder[MethodCalled <: TBoolean] private() {

def foo()(implicit ev: MethodCalled =:= TFalse): Builder[TTrue] = {
new Builder[TTrue]
}
}

object Builder {
def apply() = new Builder[TFalse]()
}

Builder().foo().foo() 无法按要求工作,但我想将错误消息设置为用户可读的内容。目前消息是

Multiple markers at this line - not enough arguments for method foo: (implicit ev: =:=[W.TTrue,W.TFalse])W.Builder[W.TTrue]. Unspecified value parameter ev. - Cannot prove that W.TTrue =:= W.TFalse. - Cannot prove that W.TTrue =:= W.TFalse.

最佳答案

在这里使用类型参数有点矫枉过正。最好只从 foo 方法返回一个功能较弱的类型:

object Builder {
trait CanFoo { def foo() : Builder }
def apply(): Builder with CanFoo = new Builder with CanFoo {
def foo() = new Builder {}
}
}
trait Builder

Builder().foo().foo() // value foo is not a member of Builder

有一个注解implicitNotFound can be used自定义错误消息,但需要使用查找的类型 (=:=) 而不是使用站点 (foo) 来定义它,so that is a pretty useless construction ...

...除非您创建自己的 =:= 替代品:

import annotation.implicitNotFound

object Called {
implicit def same[A]: Called[A, A] = instance.asInstanceOf[Called[A, A]]
private object instance extends Called[Any,Any]
}
@implicitNotFound(msg = "Cannot call this method twice") sealed trait Called[A, B]

class Builder[Foo <: TBoolean] private() {
def foo()(implicit ev: Called[Foo, TFalse]): Builder[TTrue] = {
new Builder[TTrue]
}
}
object Builder {
def apply() = new Builder[TFalse]()
}

Builder().foo().foo() // -> "error: Cannot call this method twice"

关于scala - 类型安全的生成器 : How to set compiler error message,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14292808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com