【问题标题】:List type mismatch when appending in Scala在 Scala 中追加时列表类型不匹配
【发布时间】:2020-07-31 00:58:26
【问题描述】:

假设我有以下代码:

val xs: List[Int] = List(1, 2, 3)
val ys: List[Int] = List(4, 5, 6)
val zs: List[Int] = xs.appended(ys)

最后一行没有编译错误:

错误:(162, 33) 类型不匹配;发现:需要列表 [Int]:Int val zs: List[Int] = xs.appended(ys)

如果我删除显式类型声明,那么代码会编译,但真正的问题是 错误消息出现在递归函数中,我想将附加列表作为List[Int] 类型的参数传递,因此不能选择删除显式类型。

【问题讨论】:

  • 列表的元素是整数,但您尝试插入 List[Int] 因此您得到类型未匹配。

标签: scala scala-collections


【解决方案1】:

根据scaladoc appended 方法只接受一个参数,而不是整个列表。所以下面的例子会编译:

xs.appended(ys(0))
for(x <- xs) yield ys appended x

appendAll:

xs appendAll ys
ys :++ xs

P.S.:请注意,附加到列表不是最佳的,因为它的时间与列表的大小成正比,而是更喜欢 prepend:

ys ::: xs

【讨论】:

    【解决方案2】:

    根据scala documentation appended 方法只接受一个元素,而不是集合。而移除显式类型后的 zs 类型将是 List[Any]:

    val xs = List(1, 2, 3)
    val ys = List(4, 5, 6)
    val zs: List[Any] = xs.appended(ys) // List(1, 2, 3, List(4, 5, 6))
    

    它编译,但结果将是List(1, 2, 3, List(4, 5, 6))

    您可以使用appendedAll 方法来完成您想要的操作,或者只是使用concat++ 运算符连接列表:

    val xs = List(1, 2, 3)
    val ys = List(4, 5, 6)
    val zs: List[Int] = xs ++ ys // List(1, 2, 3, 4, 5, 6)
    val as: List[Int] = xs.appendedAll(ys) // List(1, 2, 3, 4, 5, 6)
    val bs: List[Int] = xs.concat(ys) // List(1, 2, 3, 4, 5, 6)
    

    【讨论】:

    • ++ 实际上是一个concat,而不是前置
    • @Andronicus 是的,没错,但据我所知,xs 应该与 yx 连接,有错吗?
    • 是的,我并不是说它不好,只是注意到这是一种不同的方法,祝你有美好的一天!;>
    【解决方案3】:
    1. val xs: List[Int] = List(1, 2, 3)
    2. val ys: List[Int] = List(4, 5, 6)
    3. val zs: List[Int] = xs.appended(ys)
    

    在你有类型声明之前,第三行是个问题。因为当您编译代码时,编译器不会推断变量 zs 的类型,它会期望 xs.appended(ys) 的输出是 List[Int] ,因为 xs 现在是 List[Int] 如果你想要在此列表中添加一个元素,您可以执行 xs.append(1) 或任何其他整数,但您尝试插入不是 Int 的 List[Int]。

    现在,当您从第 3 行删除类型声明时,它编译成功,因为现在编译器将推断变量 zs 的类型,如果您在 REPL 上看到它会说这个变量 zs 是 List[Any]。

    现在,如果您想将列表添加到列表中并获得扁平化结果,您可以简单地使用

    val zs: List[Int] = xs ::: ys

    如果你会看到 scala 文档here

    这是附加的签名:

    final def:+[B >: A](elem: B): List[B]
    

    :+ 是附加的别名

    :++ 是 appendedAll 的别名

    正如我们从签名附加函数中看到的那样,在 B 是 Int 并且您尝试添加 List[Int] 的情况下,函数接受 B 类型的参数并返回 List[B]。

    我希望它能清除您收到编译错误的原因。

    【讨论】:

      猜你喜欢
      • 2017-03-14
      • 2013-06-08
      • 1970-01-01
      • 2012-08-27
      • 2017-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多