Scala 趣题 21 x.type ?

  class X
  val x = new X
  val y = x: x.type

  object Overload {
    def foo(arg: Any) = 1
    def foo(arg: x.type) = 2
  }

  println(Overload.foo(x))
  println(Overload.foo(y: y.type))

Explanation

If the method Overload.foo(x) is invoked, then overload resolution (SLS §6.26.3) comes into play. Both alternatives foo(Any) and foo(x.type) are potentially applicable candidates (based on the shape of the arguments). As a next step in overload resolution, the argument x is typed without an expected type and is checked against each candidate method for applicability. The type of the argument x is X (and not x.type) and therefore only the method foo(arg: Any) remains as an alternative and is chosen. This explains why Overload.foo(arg: Any) returns 1.

If a path y has singleton type x.type, then x.type and y.type are equivalent, i.e. they are interchangeable in all contexts (SLS §3.5.1). When Overload.foo(y : y.type) is invoked, then typing the argument results in y.type, and this type is compatible with the parameter type x.type and this variant is applicable. During overload resolution, the most specific alternative is chosen from the two remaining candidates, and this is foo(x.type).

Interesting: in the non-overloaded case the argument x is compatible with parameters of type x.type. This typing succeeds and therefore the method is applicable to the argument x without an explicit type ascription:

scala> def bar(arg: x.type) = 3

bar: (arg: x.type)Int

scala> bar(x)

res1: Int = 3

时间: 2024-10-07 15:46:24

Scala 趣题 21 x.type ?的相关文章

Scala 趣题 17 隐式参数和偏函数

输出是多少?   implicit val z1 = 2   def addTo(n: Int) = {     def add(x: Int)(y: Int)(implicit z: Int) = x + y + z     add(n) _   }      val addTo1 = addTo(1)  println( addTo1(2)) 原题为 implicit val z1 = 2 def addTo(n: Int) = {    def add(x: Int)(y: Int)(im

Scala 趣题 22 函数重写,位置参数,参数名

  class C {     def sum(x: Int = 1, y: Int = 2): Int = x + y   }   class D extends C {     override def sum(y: Int = 3, x: Int = 4): Int = super.sum(x, y)   }   val d: D = new D   val c: C = d   c.sum(x = 0)   d.sum(x = 0) Explanation Scala uses the

Scala 趣题 5 The missing list

回忆下Scala的集合框架, 可能有助于理解下面的题目 两个sum的结果一样吗? sumSizes(collections: [[_]]): Int =  sumSizes(((, ), (, ))) sumSizes(((, ), (, ))) Explanation Even though collections.map would appear to map an iterable to another "nice" iterable, since the Collections

Scala 趣题 16 return 语句

value = ?   def value: Int = {     def one(x: Int): Int = { return x; 1}     val two = (x: Int) => { return x; 2 }     1 + one(2) + two(3)   }      println(value) 解释 有点复杂 Explanation Scala does not complain about unreachable code, therefore the code

Scala 趣题 14 当自己调自己的时候

真是无奇不有, 下面的两个println语句哪个抛空指针,那个输出8 ?   val s1: String = s1   println(s1.length)   val s2: String = s2 + s2   println(s2.length) 解释: String类型默认被初始化成nulll null引用出现在字符串的位置按照语言规范默认被转化成字符串"null" Explanation The definitions of the values s1 and s2 are

Scala 趣题 18 偏函数对默认参数的影响

下面程序结果会是什么? package pzs object Pz018 extends App {   def invert(v3: Int)(v2: Int = 2, v1: Int = 1) {     println(v1 + ", " + v2 + ", " + v3);   }   def invert3 = invert(3) _   invert3(v1 = 2)   invert3(v1 = 2, v2 = 1) } 解释 eta展开,丢失了默认参

Scala 趣题 19 包名和对象名等不能重

package pzs object base {   class X { val context = "object base" } } package base {   class Y { val context = "package base" } } object Main extends App {   println((new base.X).context)   println((new base.Y).context) } Explanation A

Scala 趣题 4

A {   foo: Int   = (+ foo + + ) } B A {   : Int = (+ + + ) } C B {   = (+ + + ) } C Explanation Notice that bar is a val that is overridden in C. The Scala compiler will only initialize vals once, so since bar will be initialized in C it is not initi

Scala 趣题 13 私有的构造函数

首先要知道,私有成员对相伴对象是可见的 即使如此,下面的代码会有编译错误吗?   object Lives {     class Private {       def foo1: Any = new Private.C1       def foo2: Any = new Private.C2     }          object Private {       class C1 private {}       private class C2 {}     }   } 解释 Exp