scala作用域引入了导入中未显示的类型

scala作用域引入了导入中未显示的类型,scala,types,Scala,Types,我读了一篇关于scala的类型推断可能也会这样做的文章 很多: 鉴于这段代码: package A1 { case class Foo(a: Int) package object A2 { def bar() = Foo(1) } } -- import A1.A2._ object Main extends App { val a: Foo = bar() // error: not found type Foo } 它不会编译,因为Main无法看到Foo,除

我读了一篇关于scala的类型推断可能也会这样做的文章 很多:

鉴于这段代码:

package A1 {
  case class Foo(a: Int)

  package object A2 {
    def bar() = Foo(1)
  }
}

--
import A1.A2._
object Main extends App {
  val a: Foo = bar()  // error: not found type Foo
}
它不会编译,因为Main无法看到Foo,除非我们也导入A1.Foo

但是,如果删除类型注释,则可以:

import A1.A2._
object Main extends App {
  val a = bar()
}
作者认为,与java相比,java必须显式导入我们正在使用的任何类型,这将降低可读性,因为导入不再具有关于我们正在使用的类型集的完整信息

我认为他想要的是,显式或隐式使用的类型需要导入,以明确代码所依赖的内容,也许还需要帮助一些静态分析工具

对于这个问题,我想知道你是怎么想的

编辑: 正如@flavian所指出的,这与类型推断关系不大,更多的是作用域的工作原理

编辑2: 对此我有第二个想法。如果一个IDE可以自动添加importseven(如果开发人员愿意的话),那么这个问题可能并不重要


-我不认为类型推断是这里的问题。成员通过直接导入或继承在范围内传播。如果你有:

trait A1 {
  case class Foo(..)
}
object A2 extends A1 

这将正确地将Foo导入范围。同样,据我所知,这不是一个类型推断问题,而是因为导入和隐式仅通过继承传播。它更多的是关于范围界定在Scala中的工作原理,而不是其他任何东西。

我不认为类型推断是这里的问题。成员通过直接导入或继承在范围内传播。如果你有:

trait A1 {
  case class Foo(..)
}
object A2 extends A1 

这将正确地将Foo导入范围。同样,据我所知,这不是一个类型推断问题,而是因为导入和隐式仅通过继承传播。它更多地是关于范围界定在Scala中的工作方式,而不是其他任何东西。

在编译器看到的第一个示例中

val a: Foo = bar()
不知道什么是福,所以它抱怨

要修复此代码,有三个选项

// import Foo
import A1.Foo
val a: Foo = bar()

// use the fully qualified name
val a: A1.Foo = bar()

// let the compiler infer the type
val a = bar()
这些都是相同的

最后一个选项对Java不可用

作者认为这与java相比,java必须显式导入我们正在使用的任何类型

不是真的

// we can use Foo with no import
useFoo(x.getFoo());

// and we can use fully qualified names
A1.Foo foo = bar();

编译器将向编译的类文件中添加该类所需的所有类的列表。

在您的第一个示例中,编译器看到

val a: Foo = bar()
不知道什么是福,所以它抱怨

要修复此代码,有三个选项

// import Foo
import A1.Foo
val a: Foo = bar()

// use the fully qualified name
val a: A1.Foo = bar()

// let the compiler infer the type
val a = bar()
这些都是相同的

最后一个选项对Java不可用

作者认为这与java相比,java必须显式导入我们正在使用的任何类型

不是真的

// we can use Foo with no import
useFoo(x.getFoo());

// and we can use fully qualified names
A1.Foo foo = bar();

编译器将向已编译的类文件中添加该类所需的所有类的列表。

是的,您是对的。据我所知,类型推断与它所能看到的正确的公司相匹配,所以这更像是范围界定的问题。是的,你是对的。据我所知,类型推断与它所能看到的正确的公司相匹配,所以这更像是范围界定的问题。与问题无关,但与代码有关,谢谢@Odomontois。该指南非常有用。我已经编辑了我的代码。与问题无关,但与代码有关。谢谢@Odomontois。该指南非常有用。我已经编辑了我的代码。谢谢你澄清。我没有考虑到java的要点。谢谢你澄清这一点。我没有考虑过java的问题。