graphX代码中的scala类型不匹配错误

时间:2017-09-12 07:16:39

标签: scala apache-spark spark-graphx

我是scala的新手,为apache-spark学习它。我在scala中为graphX写了一个简单的函数

def foo(edge: EdgeTriplet[Map[Long, Double], Double]): Iterator[(VertexId, Map[Long, Double])] = {

    val m = edge.srcAttr

    for((k, v) <- m){
        if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
            Iterator(edge.dstId, Map(k -> v + edge.attr))

        else

            Iterator.empty

    }

}

错误

Name: Compile Error
Message: <console>:37: error: type mismatch;
 found   : Double
 required: String
                   Iterator(edge.dstId, Map(k -> v + edge.attr))
                                                          ^
<console>:35: error: type mismatch;
 found   : Unit
 required: Iterator[(org.apache.spark.graphx.VertexId, Map[Long,Double])]
    (which expands to)  Iterator[(Long, Map[Long,Double])]
           for((k, v) <- m){
                      ^
StackTrace:

为什么scala将 v 视为字符串?什么是第二次错误的原因?

按照@Alexey的建议编辑代码后,我收到错误

Name: Compile Error
Message: <console>:30: error: type mismatch;
 found   : scala.collection.immutable.Map[org.apache.spark.graphx.VertexId,scala.collection.immutable.Map[Long,Double]]
    (which expands to)  scala.collection.immutable.Map[Long,scala.collection.immutable.Map[Long,Double]]
 required: Iterator[(org.apache.spark.graphx.VertexId, Map[Long,Double])]
    (which expands to)  Iterator[(Long, Map[Long,Double])]
                 (k, v) <- edge.srcAttr
                        ^
StackTrace:

如果有帮助,我将从code

实现不同版本的sendMessage函数

1 个答案:

答案 0 :(得分:1)

不幸的是,第一个是Scala中+的常见问题。在这种情况下,您没有像您预期的那样k -> (v + edge.attr),而是(k -> v) + edge.attr+上唯一的Tuple2方法接受String。要修复它,只需添加正确的括号。

第二个错误是因为for(...) { ... }返回Unit(它被转换为foreach调用)。你遗失了yield。事实上,如果您想使用for,它应该类似于

for {
  (k, v) <- m
  x <- if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
      Iterator((edge.dstId, Map(k -> (v + edge.attr))))
    else
      Iterator.empty[(Long, Map[Long,Double])]
} yield x

我更喜欢把它写成

m.flatMap { case (k, v) => 
  if (v + edge.attr < edge.dstAttr.getOrElse(k, 10.0))
    Iterator((edge.dstId, Map(k -> (v + edge.attr))))
  else
    Iterator.empty[(Long, Map[Long,Double])]
}