拉皮条麻醉后,Scala无法识别类型

时间:2016-06-20 23:20:38

标签: scala intellij-idea web-scraping jsoup

我尝试在Scala中进行网页抓取,目前正在使用JSoup。现在我发现迭代器在Scala中不起作用,所以我做了一些pimpin'并自己写了一个迭代器。它看起来像这样:

object Pimp {

  implicit class PimpElements(es: Elements) extends Iterable[Element] {
    def iterator = new Iterator[Element] {
      var currentElem = 0

      def hasNext = currentElem < size

      def next(): Element = {
        currentElem += 1
        es.get(currentElem - 1)
      }
    }
  }
}

现在,代码不起作用,因为intelliJ或Scala无法识别我的变量ciderElement类型我想:

for (cider <- ciders; if cider.getElementsByClass("info").text() != "") {
      ciderArray += Drink(DrinkType.CIDER, cider)
}

但为什么不呢?我的next()方法会返回es.get(i),该Element应该是for (i <- 0 to ciders.size() - 1; if ciders.get(i).getElementsByClass("info").text() != "") { ciderArray += Drink(DrinkType.CIDER, ciders.get(i)) } ,并且可以在以下代码中使用:

cider

这段代码基本上和迭代器一样,但是出于某种原因得到了认可吗?根据intelliJ,Any的类型是Element,而不是html: <form method=POST action="process.php"> <input type="text" name="address"> <input type="submit"> </form> process.php: <? // visit xyz.com and check address $verified_address = "123 4 st, nowhere, NY, 10001" if ($verified_address!="") { echo '<body> <script type="text/javascript">var x=window.confirm("Is this the correct address: ' . $v_add . '?")</script> </body>'; } //the rest of the code ?>

1 个答案:

答案 0 :(得分:0)

for理解被翻译为c.withFilter(p).foreach(f)

您可能希望拨打iterator

这个问题很有意思,因为这些编码会导致更多的推断类型参数或其他影响。

我看到ElementsArrayList

TraversableLike.withFilter确实与Iterator.withFilter不同。

在修复对size(stackoverflows)的调用之后,您的示例有效。它也适用于Elements和Element的Java类型。

object Test extends App {

  case class Element(value: String)

  type Elements = java.util.ArrayList[Element]

  implicit class PimpElements(es: Elements) extends Iterable[Element] {
    def iterator = new Iterator[Element] {
      var currentElem = 0

      def hasNext = currentElem < es.size

      def next(): Element = {
        currentElem += 1
        es.get(currentElem - 1)
      }
    }
  }

  val vs = new java.util.ArrayList[Element]
  vs.add(new Element("hi"))
  vs.add(new Element("bye"))

  for (v <- vs if v.value.startsWith("h")) println(v)
}

但它也会这样:

object Test extends App {

  implicit class PimpElements(es: Elements) extends Iterator[Element] {
    var currentElem = 0 

    def hasNext = currentElem < es.size

    def next(): Element = { 
      currentElem += 1 
      es.get(currentElem - 1)
    } 
  }

  val vs = new Elements
  vs.add(new Element("hi"))
  vs.add(new Element("bye"))

  for (v <- vs if v.value.startsWith("h")) println(v)
}

Traversable将其表示形式作为类型参数进行跟踪,这可能会导致类型推断问题。这两个类都会产生一个过滤包装器。但是,Iterator在过滤时不会覆盖foreach,因此会将hasNext上的最后一个未过滤元素保存到next的调用中。可能Traversable.foreach效率更高。