类型 B => List[B] 的表达式在 Scala 中反转列表时不符合预期的类型 List[Int]



使用 foldLeft 函数处理一个在 Scala 中反转列表的函数:

def reverseWithFold(ls: List[Int]): List[Int] =
        ls.foldLeft(List[Int]())((c, _) => _:::c)

它有编译错误:Expression of type List[B_] => List[Int] doesn’t comforrm to expected type List[Int](PS:我知道我的解决方案不正确)

我能知道这是什么意思吗?在这里_:::c_表示(c, _)中的c,而cList[Int]类型,所以在我看来,_:::c应该是两个List[Int]的串联。它应该符合预期的类型,对吧?

下划线不是有效的变量名称,它们用于忽略变量。 (c, _)_ ::: c中的两个下划线是不相关的。

  • (c, _) => { ... }完全忽略第二个参数,它就消失了。
  • _ ::: c 是 lambda 表达式 x => x ::: c 的快捷方式,它期望一个x是某些无法推断的未知类型B_List[B_],因为它不是预期的,并且在您的代码中找不到它。

如果你想在第一个参数前面加上第二个参数,你必须写一些类似的东西

ls.foldLeft(List.empty[Int])((c, x) => x :: c)

甚至

ls.foldLeft(List.empty[Int])(_.::(_))

看,你可以写List(1,2,3).reduce((x, y) => x + y)List(1,2,3).reduce(_ + _).在这里,(x, y) => x + y_ + _是函数,第一个更明显,第二个是函数,其中每个下划线都替换为其中一个参数。

你在这里所做的是(c, _) => _:::c试图将两者结合起来。但是,实际上,你只是告诉scala编译器:

  1. 我有两个集合函数:c和另一个被丢弃。
  2. 此函数返回不指定类型的函数。(例如:(Int, Int) => (Int => Int) = (a: Int, _) => _ * 2

你可以在这里做的是

仅使用下划线重写:

ls.foldLeft(List.empty[Int])(_.::(_))

或重写而不丢弃:

ls.foldLeft(List.empty[Int])((acc, cur) => cur :: acc)
  • ls - 类型 List[Int] 的列表
  • foldLeft - 从lsInt元素创建新内容。
  • List[Int]() - 新的东西将是另一个List[Int].从一个空的开始。
  • (c, _) - 每一步收到正在构建的List,我们称之为c,以及来自lsInt,但不要给它一个名字(即扔掉它)。
  • _:::c - 尝试将 2 个列表连接在一起。一个是我们正在构建的c列表,另一个是......无。这不是ListInt.这是一个未命名的参数,但我们没有这些参数。在收到的 2 个参数中,一个被命名为 c,另一个被丢弃。

这是修复它的一种方法:(c, n) => List(n):::c(将 2 个列表连接在一起)

这是一个更好的解决方法:(c, n) => n::c(在此列表的头部前面添加一个新元素)

使用未命名参数:ls.foldLeft(List[Int]())(_.::(_))

相关内容

最新更新