为什么在嵌套迭代器上展平无法编译,为什么我需要类型归属?

pin*_*ons 5 scala type-inference ascription

(new Iterator[List[Int]] {
  def hasNext: Boolean = ???
  def next(): List[Int] = ???
}).flatten
Run Code Online (Sandbox Code Playgroud)

给出错误:

value flatten is not a member of Iterator[List[Int]]
[error] possible cause: maybe a semicolon is missing before `value flatten'?
[error]     }.flatten
[error]       ^
[error] one error found
Run Code Online (Sandbox Code Playgroud)

(new Iterator[List[Int]] {
  def hasNext: Boolean = ???
  def next(): List[Int] = ???
}: Iterator[List[Int]]).flatten
Run Code Online (Sandbox Code Playgroud)

作品。还将迭代器存储在 val 中。

斯卡拉版本:2.11.8

Mar*_*lic 3

我相信这个问题已通过在隐式范围中包含复合/细化类型的部分得到解决。第5867章 该问题与用于不符合隐式搜索资格的匿名类有关

我认为 aaf9198#diff-7c03397456d3b987549fd039d6b639c6R516 是第一个排除细化/匿名类对伴随隐式做出贡献的人。@odersky 你还记得动机吗?

这是一个最小的复制品

trait A {
  def foo(): Int
}
class B {
  def bar(): String = "woohoo"
}
object A {
  implicit def aToB(a: A): B = new B
}

(new A {
  override def foo(): Int = 42
}).bar()

// Error: 
// value bar is not a member of A$A12.this.A 
// possible cause: maybe a semicolon is missing before `value bar'? }).bar();
Run Code Online (Sandbox Code Playgroud)

因此,自从在 2.11 和 2.12 中flatten通过flattenTraversableOnceIterator提供了作为扩展方法时,匿名类就会出现这个问题。Iterator


以下是我在上述编辑之前的回答:

这似乎与 2.11 和 2.12 中的隐式解析有关。如果您flatten通过显式导入作为扩展方法

import scala.collection.TraversableOnce.flattenTraversableOnce
Run Code Online (Sandbox Code Playgroud)

然后它似乎起作用了。这个问题似乎从 2.13.0-M3 开始就得到了解决,其中 typer 阶段给出了

collection.this.TraversableOnce.flattenTraversableOnce[Int, List]({
  final class $anon extends AnyRef with Iterator[List[Int]] {
    def <init>(): <$anon: Iterator[List[Int]]> = {
      $anon.super.<init>();
      ()
    };
    def hasNext: Boolean = scala.Predef.???;
    def next(): List[Int] = scala.Predef.???
  };
  new $anon()
})(scala.Predef.$conforms[List[Int]]).flatten

Run Code Online (Sandbox Code Playgroud)

而在 2.13.0 版本中flatten似乎不再通过扩展方法提供

{
  final class $anon extends AnyRef with Iterator[List[Int]] {
    def <init>(): <$anon: Iterator[List[Int]]> = {
      $anon.super.<init>();
      ()
    };
    def hasNext: Boolean = scala.Predef.???;
    def next(): List[Int] = scala.Predef.???
  };
  new $anon()
}.flatten[Int](scala.Predef.$conforms[List[Int]])
Run Code Online (Sandbox Code Playgroud)

上述扩展似乎是由SLS 6.4 指示符解释的

。键入时就好像它是 { val = ; 。}