我正在努力了解如何优雅地使用scala.util.control.Exception
包。
更具体地说,我想将这段Java代码转换为功能方式:
public static boolean hostAvailabilityCheck() {
try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
return true;
} catch (IOException ex) {
/* ignore */
}
return false;
}
我可以使用try-catch-finally在Scala中做同样的事情,但我正在寻找更多功能方式。还请注意,此Java代码使用try-with-resources
,因此这意味着此代码将关闭套接字(即使发生异常):socket.close()
答案 0 :(得分:3)
---在问题澄清时编辑---
要在scala中使用函数样式的自动资源管理,最简单的方法是使用scala-arm,然后就可以编写
import resource._
def hostAvailabilityCheck():Boolean= {
managed(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).map(_=>true).opt.isDefined
}
如果你真的,真的想使用scala.util.control.Exception
你可以写:
import scala.util.control.Exception._
def hostAvailabilityCheck():Boolean= {
catching[IOException].opt(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)). isDefined
}
return false;
}
更好的是,您可以使用Try
类型执行此操作,在这种情况下,您的原始方法将变为:
def hostAvailabilityCheck():Boolean = {
Try(new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).isSuccess
}
从您的示例中不清楚您要对此做什么,但返回Try
而不是布尔值可能很有用,这样如果端口获取成功您没有在以更明确的方式重新绑定到操作系统级别之前等待端口回收。
def hostAvailabilityCheck(port: Int):Try[Socket] = {
Try(new Socket(SERVER_ADDRESS, port))
}
然后您的客户端代码可能会尝试获取一个端口,直到它实际获得一个端口:
def acquire(port: Int):Socket={
hostAvailabilityCheck(port).recoverWith(case t:Throwable => acquire(port)).get
}
这是一个天真的实现,因为它会触发无限循环,等待端口可用,并可能尝试捕获不可恢复的错误,但它应该给你一般的想法。 如果你使用0作为端口值,实现只能真正有用,在这种情况下,它将尝试各种随机端口,直到找到一个空闲的端口。