gpt4 book ai didi

scala - 为非阻塞 API 使用 Scala 延续

转载 作者:行者123 更新时间:2023-12-04 02:19:41 27 4
gpt4 key购买 nike

我正在尝试使用 Scala (2.9.0) 延续来构建一个看似阻塞的 API,但这实际上是异步的。假设你想写这样的东西:

if(ask("Continue?")) //Prompts Yes/No
name = input("Enter your name")

哪里 ask如果用户按下是,则返回一个 bool 值,并且 input要求一个值。想象一下这是从 Web 服务器调用的,其中 askinput不要阻塞任何线程,它们只是在显示带有提示的页面(释放大多数资源)之前在 Map(或 session ,无关紧要)中存储一个延续。当响应返回时,它会在 Map 中查找延续并恢复代码。

到目前为止的问题是我似乎无法找到合适的方法来定义 askinput使用延续而不将调用上下文的返回类型作为参数传递。

我得到的最接近的是做类似的事情:
#!/bin/sh
exec scala -P:continuations:enable -deprecation "$0" "$@"
!#
import util.continuations._

//Api code
def display[T](prompt: String) = shift {
cont: (Unit => T) => {
println(prompt)
cont()
}
}

//Client code
def foo() : Int = reset {
display[Int]("foo!") // <-- how do I get rid of the type annotation?
5
}

def bar() : Unit = reset {
display[Unit]("bar!")
}

println(foo())
bar()

我真的很想摆脱对 display 的调用的类型注释。 .有谁知道实现这一目标的方法?我不在乎 API 定义是否变得更丑陋,只要客户端代码变得更简单。
谢谢!

最佳答案

我终于想通了:

#!/bin/sh
exec scala -P:continuations:enable -deprecation "$0" "$@"
!#
import util.continuations._

class Display(val resume: (Unit => Any)) extends Throwable

//Api code
def display(prompt: String) = shift {
cont: (Unit => Any) => {
println(prompt)
throw new Display(cont)
}
}

//Client code
def foo() : Int = reset {
display("foo!")
5
}

def bar() : Unit = reset {
display("bar!")
}

//Framework
try {
foo()
} catch {
case d: Display => println(d.resume())
}

try {
bar()
} catch {
case d: Display => d.resume()
}

诀窍是接受返回 Any 的方法。 (Homeresque: D'oh!) 并返回 Nothing .

如果你想实现一些返回值的东西,比如 ask , 你可以做:
class Ask(val resume: (Boolean => Any)) extends Throwable

//Api code
def ask(prompt: String) = shift {
cont: (Boolean => Any) => {
println(prompt)
throw new Ask(cont)
}
}

在上面的代码中, ask 返回一个 Boolean .

关于scala - 为非阻塞 API 使用 Scala 延续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6850905/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com