score:2

Accepted answer

what happens is type ascription, and here, it is not much.

the code works just as if you had written

def p(x: int): unit = root.p(x)

as you intended. when you write x: int in the call (not in the declaration, where it has a completely different meaning) or more generally expr: type, it has the same value as expr, but it tells the compiler to check that the expr is of the given type (this is a check made a compile type, sort of an upcast, not at all a runtime check such as asinstanceof[...]) and to treat it has having that type. here, x is indeed an int and it is already treated as an int by the compiler, so the ascription changes nothing.

besides documenting a non obvious type somewhere in the code, type ascription may be used to select between overloaded method:

def f(a: any) ...
def f(i: int) ...

f(3) // calls f(i: int)
f(3: any) // calls f(a: any)

note that in the second call, with the ascription, the compiler knows that 3 is of type any, less precise than int, but still true. that would be an error otherwise, this is not a cast. but the ascription makes it call the other version of f.

you can have a look at that answer for more details: https://stackoverflow.com/a/2087356/754787

score:0

are you delegating the implementation of b.p to a.p ?

i don't see any unusual except for root.p(x:int), you can save typing by root.p(x).

trait is a way of code mixin, i think the easiest way is:

trait a {
  def p(x: int) = println("a" + x)
}

case class b extends anyref with a

val b = b() 
b.p(123)

Related Query

More Query from same tag