使用类型参数进行隐式解析时,为什么val放置很重要? [英] When doing implicit resolution with type parameters, why does val placement matter?

查看:55
本文介绍了使用类型参数进行隐式解析时,为什么val放置很重要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个文件中,我有:

trait JsonSchema[T] {
  val propertyType: String

  override def toString: String = propertyType
}

object JsonSchema {
  implicit def stringSchema: JsonSchema[String] = new JsonSchema[String] {
    override val propertyType: String = "string"
  }

  implicit def intSchema: JsonSchema[Int] = new JsonSchema[Int] {
    override val propertyType: String = "integer"
  }

  implicit def booleanSchema: JsonSchema[Boolean] = new JsonSchema[Boolean] {
    override val propertyType: String = "boolean"
  }
}

在我的主文件中:

case class MetaHolder[T](v: T)(implicit val meta: JsonSchema[T])

object JsonSchemaExample extends App {
  println(MetaHolder(3).meta.toString)
  println(MetaHolder("wow").meta.toString)
}

这很有效.现在假设我改为这样做:

That works hunky-dory. Now suppose I do this instead:

case class MetaHolder[T](v: T) {
  val meta: JsonSchema[T] = implicitly[JsonSchema[T]]
}

它不再编译.为什么?

我的目标是通过向所有内容添加 val meta 来修改scala Finch库中的匿名 Endpoint 类.到目前为止,我已经能够在没有任何花哨的事务的情况下完成此操作,但是现在我想做一些不带形状的花哨的隐式解析,以便为任意案例类提供 JsonSchema 定义.我的问题是如何在保持向后兼容性的同时做到这一点.如下所示:为想要加入的人提供jsonschema元功能,不要为不想使用元的人改变编译负担,

My goal is to modify the anonymous Endpoint classes in the scala Finch library by adding a val meta to everything. I've been able to do this without any fancy-business so far, but now I want to do some fancy implicit resolution with shapeless to provide a JsonSchema definition for arbitrary case classes. My question is how to do this while maintaining backward compatibility. As in: provide the jsonschema meta feature for people who want to opt in, don't change the compilation burden for anyone who does not want to use meta,

如果我改走带有添加的隐式参数的第一条路线,那不是每个人都需要添加特殊的导入内容吗?还是我遗漏了一些东西,还会保持向后兼容性吗?

If instead I go the first route, with an added implicit parameter, wouldn't that require a special import to be added by everyone? Or am I missing something and would backward compatibility still be maintained?

推荐答案

参数之间的 implicit x:X 与体内的 implicitly [X] 之间存在很大差异.

There is big difference between implicit x: X among parameters and implicitly[X] inside body.

当您说 implicitly [X] 时,这意味着现在检查在当前范围内是否存在隐式的 X ".

When you say implicitly[X] this means "check now whether in the current scope there is an implicit X".

当您说 def foo(...)(隐式x:X)= ... 时,这表示请稍后检查 foo 在范围内被调用时的呼叫站点将有一个隐式的 X (现在假设在 foo 内部,而无需检查是否存在)".

When you say def foo(...)(implicit x: X) = ... this means "check later when foo is called that in the scope of the call site there will be an implicit X (and for now inside foo just assume without checking that there is)".

Foo(...)(隐式x:X)类似于后者,检查构造函数被调用时是否存在隐式 X "

class Foo(...)(implicit x: X) is similar to the latter, "check when constructor is called that there will be an implicit X".

关于用户是否必须导入.如果将 X 类型的隐式对象放到 X 的伴随对象中,则会自动找到它们(应放置 X [Y] 类型的隐式对象到 X Y 的伴随对象).如果将它们放在其他位置,则必须将它们导入当前作用域.

Regarding whether users have to import or not. If you put implicits for type X to companion object of X then they will be found automatically (implicits for type X[Y] should be put to companion object of either X or Y). If you put them somewhere else then they have to be imported to the current scope.

这篇关于使用类型参数进行隐式解析时,为什么val放置很重要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆