官术网_书友最值得收藏!

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 cOrDD 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.

主站蜘蛛池模板: 赫章县| 冕宁县| 嘉定区| 武胜县| 从江县| 长宁区| 竹山县| 博白县| 湘乡市| 大安市| 石家庄市| 平山县| 绥德县| 大方县| 龙游县| 桐梓县| 永福县| 辽宁省| 麦盖提县| 南乐县| 延边| 金湖县| 海盐县| 兴义市| 哈巴河县| 天台县| 梅州市| 马公市| 图们市| 始兴县| 台北县| 无棣县| 高台县| 开原市| 荥经县| 陇川县| 布尔津县| 乌鲁木齐市| 建昌县| 大兴区| 特克斯县|