Ошибка несоответствия типа scala в коде 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:
Почему Скала рассматривает 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:
Если это поможет, я реализую другую версию функции sendMessage из этого кода
1 ответ
Во-первых, это общая проблема с +
в Скале, к сожалению. В этом случае у вас нет 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])]
}