微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Scala 3 (Dotty)

如何解决Scala 3 (Dotty)

是否有一种单行方式来提供对隐式可用的值的命名引用(即使用 using 语法可用)而无需即将成为-不推荐使用 implicit 关键字?根据 the docs,我希望以下内容能够正常工作(在 SBT 下,scalaVersion := "3.0.0-M2"

trait Greeter {
  def sayHello(username: String): Unit
  def shutdown(): Unit
}

def greet(username: String)(using g: Greeter): Unit = {
  g.sayHello(username)
}

object Foo extends App {
  given greeter: Greeter = new Greeter {
    override def sayHello(username: String): Unit = println(s"Hello,${username}!")

    override def shutdown(): Unit = println("Shutting down")
  }
  
  try {
    greet("world")
  } finally {
    greeter.shutdown()
  }
}

但这失败了

[error] -- Error: /path/to/project/src/main/scala/Foo.scala:12:15 
[error] 12 |  given greeter: Greeter = new Greeter {
[error]    |               ^
[error]    |               end of statement expected but ':' found
[error] -- [E040] Syntax Error: /path/to/project/src/main/scala/Foo.scala:12:17 
[error] 12 |  given greeter: Greeter = new Greeter {
[error]    |                 ^^^^^^^
[error]    |                 ';' expected,but identifier found

现在:我可以通过多种方式解决这个问题,但要么文档令人困惑(或错误),要么我误解了一些非常基本的东西。

解决方法 1(如建议的 here):

lazy val greeter: Greeter = new Greeter {
  override def sayHello(username: String): Unit = println(s"Hello,${username}!")
  override def shutdown(): Unit = println("Shutting down")
}
given Greeter = greeter
...

但我希望能够在单个表达式中而不是两个表达式中执行此操作。相同的注释适用于先定义给定然后将其绑定到名称

given Greeter with {
  override def sayHello(username: String): Unit = println(s"Hello,${username}!")

  override def shutdown(): Unit = println("Shutting down")
}
val greeter: Greeter = implicitly

特别是因为我认为 implicitly 将在 3.1 中被弃用并在 3.2 中消失。

我们也可以将给定对象的调用包装在函数中来解决这个问题:

def greet(username: String)(using g: Greeter): Unit = {
  g.sayHello(username)
}

def shutdown(using greeter: Greeter): Unit = {
  greeter.shutdown()
}  

given Greeter with {
  override def sayHello(username: String): Unit = println(s"Hello,${username}!")

  override def shutdown(): Unit = println("Shutting down")
}

try {
  greet("world")
} finally {
  shutdown
}

但这对我来说似乎是样板。

解决方法

事实证明

given x: T = ...

在修订版 M2 和修订版 RC1 之间添加了语法。以下适用于 scalaVersion := "3.0.0-RC1"

trait Greeter {
  def sayHello(username: String): Unit
  def shutdown(): Unit
}

def greet(username: String)(using g: Greeter): Unit = {
  g.sayHello(username)
}

object Foo extends App {
  given greeter: Greeter with {
    override def sayHello(username: String): Unit = println(s"Hello,${username}!")
  
    override def shutdown(): Unit = println("Shutting down")
  }
  
  try {
    greet("world")
  } finally {
    greeter.shutdown()
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。