- Learn Scala Programming
- Slava Schmidt
- 402字
- 2021-06-10 19:35:45
Type inference
The preceding type hierarchy is quite important for understanding how type inference works. Type inference is a mechanism that the compiler uses to guess the type of an expression or a method if the definition of its type is omitted. The same also applies to the type parameters of polymorphic methods or generic classes and sometimes to anonymous function parameter types as well. This inference aims to provide the most specific type possible while obeying all of the existing constraints. The compiler does this by walking the hierarchy tree and finding the least upper bound. Let's look at an example:
case class C(); class D(); case class E()
def iOrB(i: Int, s: Boolean)(b: Boolean): AnyVal = if (b) i else s
def iOrS(i: Int, s: String)(b: Boolean): Any = if (b) i else s
def sOrC(c: C, s: String)(b: Boolean): java.io.Serializable = if (b) c else s
def cOrD(c: C, d: D)(b: Boolean): AnyRef = if (b) c else d
def cOrE(c: C, e: E)(b: Boolean): Product with Serializable = if (b) c else e
Here, we specified the return types as the compiler infers them. For the first two cases, you can easily follow the hierarchy of Scala types to understand how the compiler did the inference. The last three are a bit more complicated:
- In sOrC, the inferred type is java.io.Serializable. The reason for this is that Scala's String is just an alias for java.lang.String, which extends java.io.Serializable. All case classes in Scala extend Product with Serializable by default and Serializable extends java.io.Serializable. Therefore, java.io.Serializable is the least upper bound in this case.
- In cOrD, D is not a case class, and therefore it does not extend anything but the AnyRef, which becomes an inferred type.
- In cOrE, both C and E are case classes, and so the compiler can infer the most specific type, that is, Product with Serializable.
In fact, the preciseness of the compiler can go quite far, as the following example demonstrates:
trait Foo { def foo: Int }
case class F() extends Foo {def foo: Int = 0}
case class G() extends Foo {def foo: Int = 0}
def fOrG(f: F, g: G)(b: Boolean):
Product with Serializable with Foo = if (b) f else g
Here, we can see that the inferred type of fOrG is a compound type with three members.
- 計算思維與算法入門
- Visual FoxPro程序設計教程
- Mastering Ember.js
- JMeter 性能測試實戰(第2版)
- Mastering Entity Framework
- 機械工程師Python編程:入門、實戰與進階
- 實戰Java高并發程序設計(第3版)
- UML 基礎與 Rose 建模案例(第3版)
- HTML5 APP開發從入門到精通(微課精編版)
- HTML 5與CSS 3權威指南(第3版·上冊)
- Linux C編程:一站式學習
- OpenGL Data Visualization Cookbook
- iOS自動化測試實戰:基于Appium、Python與Pytest
- INSTANT Yii 1.1 Application Development Starter
- Mastering AWS Security