我是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函数答案 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])]
}