简体   繁体   中英

Different type inference for `def` and `val` in Scala

I observed a difference in Scala's type inference when applied to def and val .

Using def , I can define an abstract nullary method const returning some value of type Int => Int . When implementing const with a function literal, I need not supply a parameter type, as it can be inferred by the compiler:

trait D {
  def const: Int => Int
}
object D extends D {
  def const = i => i + 1
}

This is fine. (On the downside, a new function instance is being created for every access to D.const .)

Now consider an analogous construction using val :

trait V {
  val const: Int => Int
}
object V extends V {
  val const = i => i + 1
}

This will not compile, failing with

error: missing parameter type
   val const = i => i + 1
               ^

Why?

If you build this code with the option -Xprint all , you will see that :

abstract trait V extends scala.AnyRef {   
<stable> <accessor> def const: Int => Int
};

final object V extends java.lang.Object with V with ScalaObject {

def this(): object V = {
  V.super.this();
  ()
};

private[this] val const: <error> => <error> = ((i: <error>) => i.+(1));
<stable> <accessor> def const: <error> => <error> = V.this.const
}

So the error occurs at the creation of private val and accessor. th compilator try to evaluate the value affected to the val const before creating the accessor def const.

if you look to the val const defined in trait, you see that the creation of private val was disabled because it's only a definition for the def const accessor.

I think the inference type with previous definition ( in trait or superclass) occurred only when he try to create the accessor, not for evaluate a value.

And for the last def const , the type is only based on the private[this] val const type : error => error

As of Scala 2.9.1, this is “as speced”. Citing Martin Odersky from SI-2742 :

For methods, return types in inherited abstract methods are taken as expected type of the right hand side. For values there is no such rule. So this would be a spec enhancement request, as I see it.

The ticket is low priority and has remained unchanged since its first discussion in late 2009, so it seems unlikely to change anytime soon.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM