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

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

主站蜘蛛池模板: 沁源县| 乌拉特后旗| 临泽县| 荆门市| 吴川市| 裕民县| 芦溪县| 康平县| 阜南县| 镇雄县| 千阳县| 托克托县| 隆子县| 册亨县| 新绛县| 昌图县| 呼伦贝尔市| 凯里市| 绵阳市| 西平县| 蚌埠市| 沅江市| 阳朔县| 视频| 曲周县| 荔波县| 岢岚县| 苍南县| 南皮县| 南宫市| 东宁县| 宣恩县| 秦安县| 霍林郭勒市| 宁津县| 佛山市| 莎车县| 鞍山市| 长阳| 乌拉特前旗| 乌海市|