Identification of two-character type characters

Suppose we define an interface as:

trait Foo[A] {
  val value: A
  def perform(v: A): Unit
}

and compile this code:

val n: Foo[_] = null
n.perform(n.value)

It looks perfect ... but we get a cryptic error:

error: type mismatch;
found   : n.value.type (with underlying type _$1)
required: _$1
n.perform(n.value)
            ^

So ... why is this happening? I know how to get around this; I'm just curious. Thank!

+4
source share
2 answers

Here you are not using a raw type, you are using a wildcard. It looks like

List<?> list = null;
list.add(list.get(0));

It does not compile, since the compiler works in several stages:

  • The value is returned n.value, the compiler marks the value representing the pattern.
  • A method is executed n.performwhere the compiler only knows that the argument is a different template.

. . , get-and-put. get the put , , Scala , . :

val n: Foo[_] = null
def rebox[A](x: Foo[A]) = x.perform(x.value)
rebox(n)

a NullPointerException.

+3

Foo[X] forSome {type X}. : , T , Foo [T]

T - . .

-Xprint:all

jatinpuri@jatin:~/Desktop$ scalac -Xprint:all T.scala 
[[syntax trees at end of                    parser]] // T.scala
package <empty> {
    ...
    abstract trait Foo[A] extends scala.AnyRef {
      val value: A;
      def perform(v: A): Unit
    };
    val n: Foo[_$1] forSome { 
      <synthetic> type _$1
    } = null;
    n.perform(n.value)
  }
}

n.value _$1. n.perform() . . :

scala> trait Foo[A] {
     |   val value: A
     |   def perform(v: A): Unit
     | type i = A
     | }
defined trait Foo


scala> type I = Foo[X] forSome {type X}
defined type alias I

scala> val n : I = null;
n: I = null

scala> n.value:(I#i)
<console>:16: error: type mismatch;
 found   : n.value.type (with underlying type X)
 required: X
              n.value:(I#i)

I # X. n.value -

+3

All Articles