Синтаксис для именованных заданных / используемых объектов в Scala 3 (Dotty)

Есть ли однострочный способ предоставить именованную ссылку на значение, которое должно быть неявно доступным (т. Е. Доступным с using синтаксис) без устаревшего implicitключевое слово? Согласно документам , я бы ожидал, что следующее будет работать (под 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 (как предлагается здесь ):

      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
}

но мне это кажется шаблонным.

1 ответ

Оказывается,

      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()
  }
}
Другие вопросы по тегам