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
}

但这对我来说似乎是陈词滥调。

结果是

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()
}
}

相关内容

  • 没有找到相关文章

最新更新