5

implicitScala 2 中的关键字和Scala 3 中的given+有什么区别using?只是implicit被分成了两个关键字,还是语义也不同,如果是,如何?

4

2 回答 2

4

在大多数情况下,它们是相同的。但是,implicit不再用于多个不同的概念。文档更详细,但这里是它们的摘要:

使用

声明参数时,usingimplicit. 但是,当显式传递隐式参数时,您必须使用using

def foo(using bar: Bar) = ???
foo(using Bar()) //Cannot use just foo(Bar()) as you would in Scala 2

您还可以在 Scala 3 中使用隐式按名称参数。


给定

Givens 也与隐式 vals/objects/methods 非常相似。

它们的一个好处是它们可以是匿名的,编译器将为它们生成一个名称,看起来就像given_F_X_Y给定的类型是F[X, Y]. 更多细节在这里

另一个变化是给定的类型必须显式编写——它不能像 Scala 2 中的隐式那样推断出来。

不带参数的给定映射到implicit object. given foo: Foo with {...}变得公正implicit object foo extends Foo {...}

带参数的给定类似于implicit def只接受更多implicit参数的给定。

given listOrd[T](using ord: Ord[T]): Ord[List[T]] with { ... }
//^^ this maps to this vv
class listOrd[T](implicit ord: Ord[T]) extends Ord[List[T]] { ... }
final implicit def listOrd[T](implicit ord: Ord[T]): listOrd[T] = new listOrd[T]

仅作为别名的给定implicit def如果只是引用,则变为 an,否则为 an implicit lazy val

val foo: Foo
given Foo = foo

会变成final implicit def given_Foo = foo(注意编译器生成的名称),但是

given foo: Foo = new Foo()

会变成final implicit lazy val foo: Foo = new Foo()因为new Foo()不应该进行不必要的计算。


您现在可以定义一个给定的实例,而不是使用从toimplicit def的隐式转换。ABConversion[A, B]

Dotty 中仍然可以使用隐式类,但可以直接定义扩展方法。虽然扩展中的方法不能采用自己的类型参数,但它们比隐式类更易于使用。

Scala 3 中的一个额外变化summon是一个类似 的方法implicitly,但它可以返回比所请求的类型更具体的类型。

于 2020-12-12T22:18:27.163 回答
2

语义也不同。在 Scala 2Not中可以使用歧义技巧来定义

trait Not[A]
object Not {
  implicit def default[A]: Not[A] = null
  implicit def ambig[A](implicit a: A): Not[A] = null
}

implicitly[Not[Int]] // compiles

implicit val s: String = null
// implicitly[Not[String]] // doesn't compile

但是在 Scala 3 中这不起作用,因为歧义错误没有传播

trait Not[A]
object Not {
  given [A]: Not[A] = null
  given [A](using a: A): Not[A] = null
  // given ambig[A](using a: A): Not[A] = null
}

summon[Not[Int]] // compiles

given String = null
summon[Not[String]] // compiles

应该scala.util.NotGiven改用

summon[NotGiven[Int]] // compiles

given String = null
// summon[NotGiven[String]] // doesn't compile

(在 3.0.0-M3-bin-20201211-dbc1186-NIGHTLY 中测试)

http://dotty.epfl.ch/docs/reference/contextual/givens.html#negated-givens

http://dotty.epfl.ch/docs/reference/changed-features/implicit-resolution.html

于 2020-12-13T04:34:10.260 回答