斯卡拉,为什么我不需要导入推导类型
我觉得我应该以这样一个事实开头,即我正在用sbt构建我的项目。斯卡拉,为什么我不需要导入推导类型
我的问题是,如果在编译时某个方法返回某个未导入类型的东西,则在我调用该方法的文件中,只要我使用类型推断,就会编译所有内容。一旦我尝试将我的函数的返回值创建的var/val分配给unimported类型,我得到一个编译器错误。
可以说我有两个包中的两个类。包中的类为App
,包main
和类Imported
包libraries
。让我们进一步说,我们在包main中有一个类ImportedFactory
,并且这个类有一个创建类型为Imported的对象的方法。
此代码编译就好:
class App() {
// method return object of type Imported
val imp = ImportedFactory.createImportedObject()
}
这不:
class App() {
// method return object of type Imported
val imp : Imported = ImportedFactory.createImportedObject()
}
这又一次做:
import libraries.Imported
class App() {
// method return object of type Imported
val imp : Imported = ImportedFactory.createImportedObject()
}
这似乎是很奇怪的行为。这对编译时类型推断的语言来说是正常的,而且由于我的无知,直到现在我还没有注意到它在go/C++中?
两种有效方法之一(导入&显式类型与传染)有优点/缺点比其他? (当然,期望的是一个更明确和详细,另一个更短)
这是黑魔法还是斯卡拉编译器以相当直接的方式完成这些扣除?
注:您会得到更好的搜索结果与术语类型推断
随着val imp = ImportedFactory.createImportedObject()
你让编译器弄清楚什么类型的imp
应根据类型推断。无论什么类型的createImportObject
返回,这就是imp
类型。
使用val imp : Imported = ImportedFactory.createImportedObject()
您明确指出imp
是和Imported
。但编译器不知道你的意思,除非你......导入......它。
两种方法各有优点:
推断类型
推断类型,当你扔在一起的代码,其中类型应该是显而易见的是巨大的:
val i = 1 // obviously `i` is an int
val j = i + 10 // obviously still an int
这也是很大的对于当地的瓦尔/瓦尔型这种类型会太痛苦写
val myFoo: FancyAbstractThing[TypeParam, AnotherTypeParam[OhNoMoreTypeParams]] = ...
// vs
val myFoo = FancyThingFactory.makeANewOne()
缺点是,如果您已允许公共def/val具有推断类型,则确定如何使用该方法可能会更困难。由于这个原因,省略类型注释通常只用于简单的常量,并且在“客户代码”不必看的本地vals/vars中。
明确的类型
当你想要写库上下的代码(即公共丘壑/ DEFS),惯例是显式输入。
可能就是这个最简单的原因是因为这样的:
def myLibraryMethod = {
// super complicated implementation
}
是很难理解比
def myLibraryMethod: String = {
// super complicated implementation
}
另一个好处明确,输入你的代码是当你想揭露less-具体类型比实际值多:
val invalidNumbers: Set[Int] = TreeSet(4, 8, 15, 16, 23, 42)
在这个例子中,你不要w蚂蚁客户端代码需要注意,您的invalidNumbers
实际上是一个TreeSet
。这是一个实现细节。在这种情况下,你隐藏了一些信息,虽然是真的,但会分散注意力。
导入的唯一事情就是在当前范围内提供一个不完全限定的名称。你也可以同样这样写:
的原因,你import libraries.Imported
是为了使较短的名称Imported
可为你写。如果你让编译器推断出这个类型,你就不会在代码中提到这个类型,所以你不必导入它的较短的名字。
顺便说一下:这与C++中的动态转换无关。在你的代码中工作的唯一机制是类型推断。
我挪用了动态铸造这个术语,这可能确实对我的问题造成了很多混淆(并且缺乏建议),对不起。 – George