Scala 3 (Dotty) 中命名 given/using 对象的语法
Syntax for named given/using objects in Scala 3 (Dotty)
是否有一种单行方法可以提供一个 named 对隐式可用(即可用 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()
}
}
是否有一种单行方法可以提供一个 named 对隐式可用(即可用 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()
}
}