【问题标题】:Scala for comprehension returns type mismatch; found : UnitScala 用于理解返回类型不匹配;发现:单位
【发布时间】:2018-11-23 06:34:38
【问题描述】:

我想了解为什么这段代码无法编译:

  def comb(list: List[(Char, Int)]): List[(Char, Int)] = {
    for (tuple <- list) {
      tuple match {
        case p if (p._2 > 1) => List(p) :: List((p._1, p._2 - 1))
        case _               => List(tuple)
      }
    }
  }

如果我在函数外部执行此代码并直接应用于List,则它可以工作。我想我的问题是,我不明白值是如何返回的。

我从 Eclipse 收到此错误:

类型不匹配;找到:所需单位:List[(Char, Int)]

我查看了另一个答案,主要是 if 声明,但我仍然不明白。

【问题讨论】:

    标签: scala


    【解决方案1】:

    没有yieldfor() 等价于foreach(),它不返回任何感兴趣的内容(Unit),但是comb() 的定义说它应该返回List[(Char, Int)],所以编译器抱怨。

    我们可以在for() 之后添加yield,但还有另一个问题:代码在for() 内创建List 值,这意味着结果将是一个List 和许多更小的@987654332 @s。这仍然与方法返回类型不匹配。

    所以我们可以通过.flatten 内部的Lists 得到一个List 的元组,这最终将匹配返回类型。

    def comb(list: List[(Char, Int)]): List[(Char, Int)] = {
      for (tuple <- list) yield {
        tuple match {
          case p if p._2 > 1 => p :: List((p._1, p._2 - 1))
          case _             => List(tuple)
        }
      }
    }.flatten
    
    comb(List(('a',9),('b',5),('c',1)))
    //res0: List[(Char, Int)] = List((a,9), (a,8), (b,5), (b,4), (c,1))
    

    值得注意的是,只有一个生成器(&lt;- 部分)的 for() 推导等效于 map() 调用。 map() 调用后跟.flatten 等效于flatMap() 调用。所以上面等价于:

    def comb(list: List[(Char, Int)]): List[(Char, Int)] =
      list.flatMap{case (c,i) => (c,i) :: (if (i>1) (c,i-1)::Nil else Nil)}
    

    【讨论】:

    • 谢谢!它有效,并且知道我学到了更多。我使用 for 理解只是为了尝试不同的选项,这只是练习的第一部分,但我明白了你的意思。
    【解决方案2】:

    你需要一个收益在那里

    def comb(list: List[(Char, Int)]): List[(Char, Int)] = {
    for (tuple <- list) yield {
      tuple match {
        case p if (p._2 > 1) => p :: List((p._1, p._2 - 1))
        case _               => List(tuple)
      }
    }
    }
    

    然而,这可能不是 Scala 中最好的方法。您可以尝试这样的替代方法

    def comb(list: List[(Char, Int)]): List[(Char, Int)] = {
    list.map{
     case(char:Char,int:Int) if(int >1)=> (char,int-1)
     case(char:Char,int:Int) => (char,int)
    }
    }
    

    【讨论】:

    • 感谢您的回答,我真的很感激,但我将其他回复标记为答案,因为它也解释了我的代码错误的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 2018-10-19
    • 1970-01-01
    • 2018-10-24
    相关资源
    最近更新 更多