0

我有一些使用 Javaslang 的相当复杂的代码。如果我将它编译成一个 jar,它运行良好。但是,当我尝试在 Eclipse 中进入它进行调试时,Eclipse 将其标记为编译错误并在它到达该行时死亡。特别奇怪的部分是,这在一周前有效,并且代码在此期间没有更改。

我尝试过的事情:

  • 清理项目(包括取消选中“自动构建”)
  • 从 Eclipse 中删除项目,删除 .project 和 .settings,从头开始重新导入
  • 从 Eclipse 中删除项目,删除 .project、.classpath、.settings,执行 mvn eclipse:eclipse,重新导入

Maven 构建这个没有错误[在 Eclipse 和命令行中]。我可以运行这个依赖的项目并让它从 JAR 中访问这个代码,所以我知道它可以工作。我只是不能让 Eclipse 在“运行”或“调试”模式下访问项目中的代码。

    Seq<Tuple2<StateProbabilityVector, ScenData>> resultStateProbs =
        futures.
            flatMap(Future::get).
            toList();

    // Update the target counts.
    // THIS ENTIRE STATEMENT IS THE ERROR
    Seq<Tuple2<ScenState, Probability>> result =
        resultStateProbs.flatMap(tuple -> tuple.apply((spv, baTargetCount) ->
    {
        return spv.getStateProbList().
        peek(sp -> logger.debug("Checking if {} > {}: {}",
                               sp.getProbability(),
                               intermediateMinProb,
                               sp.getProbability().greaterThan(intermediateMinProb))).
        filter(sp -> sp.getProbability().greaterThan(intermediateMinProb)).
        map(sp -> updateScenarioData(sp, baTargetCount, dupStateInfo));
    }));

// signature for updateScenarioData
protected abstract Tuple2<ScenState, Probability> updateScenarioData(StateProbability stateProb,
                                                                         ScenData scenData,
                                                                     DSI dupStateInfo);
// truncated def of StateProbabilityVector
@Getter @ToString @Builder
public class StateProbabilityVector {
 @NonNull
    private final Seq<StateProbability> stateProbList;
}

所以类型都是正确的,但 Eclipse 声称:

> Type mismatch: cannot convert from Object to Iterable<? extends
> Object>    
> Type mismatch: cannot convert from Seq<Object> to
> Seq<Tuple2<ScenState,Probability>>
4

1 回答 1

1

正如Nándor 评论的那样,这可能归结为 Eclipse 编译器和 javac 之间的差异,并且可以通过在正确位置使用类型见证来解决问题。为了找到正确的位置,我首先要分解函数方法链并提取一些局部变量:

Seq<Tuple2<ScenState, Probability>> result =
  resultStateProbs.flatMap(tuple -> {
    Seq<Tuple2<ScenState, Probability>> filteredAndUpdated =
      tuple.apply((spv, baTargetCount) -> {
        Seq<StateProbability> stateProbList = spv.getStateProbList();

        stateProbList.peek(sp -> {
          logger.debug("Checking if {} > {}: {}", sp.getProbability(), intermediateMinProb, sp.getProbability().greaterThan(intermediateMinProb));
        });

        Seq<StateProbability> filtered = stateProbList.filter(sp ->
          sp.getProbability().greaterThan(intermediateMinProb));

        Seq<Tuple2<ScenState, Probability>> updated = filtered.map(sp ->
          updateScenarioData(sp, baTargetCount, dupStateInfo));

        return updated;
      });
    return filteredAndUpdated;
  });

如果您使用 Eclipse 的提取变量重构,它本身可能会告诉您它在哪里推断出错误的类型,并且显式声明局部变量的正确类型可能足以自行解决问题。

如果不是,它至少应该缩小错误范围,并准确地向您显示 Eclipse 在调用链中的哪个位置出现了问题。然后,您可以使用类型见证来修复它,或者,如果所有其他方法都失败,则使用显式强制转换,然后(添加了该类型信息)可能再次内联变量,尽管这段代码足够密集,我可能会将它们留在里面。


旁注:

  1. peek()只会调试第一个StateProbability——这是你的意图吗?
  2. 考虑添加一个greaterThan()方法,StateProbability这样您就不必重复调用getProbability().greaterThan(). (如果 #1 的答案是“否”,那么这个方法也是放置调试语句的好地方。)
  3. 考虑在其上添加一个方法,SceneState该方法将返回一个预过滤列表,例如Seq<StateProbability> SceneState.allGreaterThan(Probability).
于 2017-07-13T21:05:52.737 回答