gpt4 book ai didi

scala - 传播 Scala 类型参数

转载 作者:行者123 更新时间:2023-12-02 17:28:28 27 4
gpt4 key购买 nike

这是我认为人们通常希望在 Scala 中做的事情,但如果我能在任何地方找到一个例子,我就该死了。

这段代码由于类型删除而无法编译,但它演示了我正在努力完成的事情:

def parse[T](json: JsValue): T = {
json.validate[T] match {
case JsSuccess(x, _) => x
case JsError(errors) => throw new MyException(errors.toString)
}
}

我看到类型信息被删除的方式是添加一个隐式的 ClassTag 参数:

def parse[T](json: JsValue)(implicit ct: ClassTag[T]): T = {
json.validate[T] match {
case JsSuccess(x, _) => x
case JsError(errors) => throw new MyException(errors.toString)
}
}

但是……现在呢?如果那个 validate 方法接受了一个 ClassTag 参数,我想我可以直接传递它:

json.validate(ct)

...但它没有,它需要一个隐式的 Reads[T],我无法辨别如何从 ClassTag[T] 中获取到 Reads[T]

是否可以像这样任意传播类型信息?如果是这样,如何?还是我的期望太高,这是不可能的,这就是我找不到任何例子的原因?

最佳答案

这不是类型删除问题。您可以将类型参数 T 传递给 validate 并且它还没有被删除。问题是您需要范围内可用的隐式 Reads[T]。您可以通过将其添加为上下文绑定(bind)来轻松解决此问题:

def parse[T: Reads](json: JsValue): T = {
json.validate[T] match {
case JsSuccess(x, _) => x
case JsError(errors) => throw new MyException(errors.toString)
}
}

这种脱糖可以:

def parse[T](json: JsValue)(implicit r: Reads[T]): T = {
json.validate[T] match {
case JsSuccess(x, _) => x
case JsError(errors) => throw new MyException(errors.toString)
}
}

请注意,此方法或多或少等同于编写 json.as[T],尽管有不同的异常(exception)情况。


我想混淆的根源可能是错误:

<console>:16: error: type mismatch;
found : x.type (with underlying type Any)
required: T
case JsSuccess(x, _) => x
^

但第一个错误其实说明了问题:

<console>:15: error: No Json deserializer found for type T. Try to implement an implicit Reads or Format for this type.
json.validate[T] match {
^

第二个错误是由第一个错误引起的(编译器可能应该停在那里),所以第二个错误在这种情况下没有帮助。

关于scala - 传播 Scala 类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36654532/

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