在scala中尝试递归调用

时间:2015-02-02 00:30:45

标签: xml scala

问题1)我试图在scala中从YQL中提取货币。下面提到的getXML获取其余的URL并返回xml节点。在我的主代码中,我想再次调用getXML,以防万一睡眠后发生10000毫秒的故障。

请告知如何实现如何在我尝试在失败代码中编写getXML时不进行编译。

def getXML(url: String): Try[scala.xml.Node] =  
 {

 Try(XML.loadString(Source.fromURL(new URL(url)).mkString))

 }


val nodes = getXML(ccyurl) match {
  case Success(node) => node
  case Failure(f) => {
      Thread.sleep(10000)
      /****/
}  

问题2) 还有一个问题。我是编程的新手,而且scala有点磕磕绊绊。 我已经定义了一个函数

def exchangelookup(s :String): Try[String] = Try(exchange_currency_map(s))

它的用法如下所述,它是数组中的第4项。

exchangelookup(Cols(0).takeRight(3)) match {case Success(x) => x
                               case Failure(x) =>       FileParserlogger.error(x.getMessage()) } , //ExchangeCurrency 4

但是当我在另一个数组中使用它作为静态(4)我得到"键入不匹配;发现:任何要求:  字符串"

val fxconversion = fxconvertor(getexchange(nodes,static(10)),getexchange(nodes, exchange_to_real_ccy_map.getOrElse(static(4),static(4))))

提前致谢。

1 个答案:

答案 0 :(得分:2)

您需要使用recoverWithFailure恢复另一个Try。一个简单的用法看起来像这样:

def getXML(url: String): Try[scala.xml.Node] = {
    Try(XML.loadString(io.Source.fromURL(new URL(url)).mkString))
        .recoverWith {
            case _ => {Thread.sleep(10000); getXML(url)}
        }
}

然而,如果它永远不会成功,那么这将永远运行(并且永远,我的意思是直到它从递归过深到达堆栈溢出),这是我们可能不想要的。但是,为最大重试次数添加计数器会很容易:

def getXML(url: String)(retries: Int): Try[scala.xml.Node] = {
    Try(XML.loadString(io.Source.fromURL(new URL(url)).mkString))
        .recoverWith {
            case _ if(retries > 0) => {
                Thread.sleep(10000)
                getXML(url)(retries - 1)
            }
        }
}

另一个潜在的问题是它阻止了代码。根据您的使用情况,这可能没问题,但如果您的程序需要并发,则可以考虑使用Future而不是TrygetXML的实现几乎完全相同,但它的用法会大不相同。