What's different between “def apply[T](c:T)” and “type T;def apply(c:T)”

前端 未结 1 987
南方客
南方客 2021-01-26 05:40

I have this program:

object B{
  def apply[T](c:T)={}
}

object C{
  type T
  def apply(c:T)={}
}

object A extends App{
  val d=B{println(1);2}
  val e=C{printl         


        
相关标签:
1条回答
  • 2021-01-26 06:21

    The type of a block is the type of the last expression on the block. So

    { println(...); 2 } 
    

    has type Int.

    Difference between B and C is difference in type inference between type members and type parameters (1, 2).

    object B{
      def apply[T](c:T)={}
    }
    
    object C{
      type T
      def apply(c:T)={}
    }
    
    class C1[T]{
      def apply(c:T)={}
    }
    
    val d: Unit = B{println(1);2}
    // val e: Unit = C{println(1);2} // doesn't compile
    val e1: Unit = (new C1){println(1);2}
    
      // scalacOptions ++= Seq("-Xprint:typer", "-Xprint-types")
    // val d: Unit = A.this{A.type}.B.apply{[T](c: T)Unit}[Int]{(c: Int)Unit}({
    //   scala.Predef.println{(x: Any)Unit}(1{Int(1)}){Unit};
    //   2{Int(2)}
    // }{2}){Unit};
    // val e: Unit = A.this{A.type}.C.apply{(c: A.C.T)Unit}({
    //   println{<null>}(1{Int(1)}){<null>};
    //   2{Int(2)}
    // }{<null>}){<error>};
    // val e1: Unit = new A.C1[Int]{A.C1[Int]}{()A.C1[Int]}(){A.C1[Int]}.apply{(c: Int)Unit}({
    //   scala.Predef.println{(x: Any)Unit}(1{Int(1)}){Unit};
    //   2{Int(2)}
    // }{2}){Unit};
    

    In C type T remains abstract

    Use of abstract type in a concrete class?

    Concrete classes with abstract type members

    There is thesis about type inference in Scala:

    Plociniczak, Hubert ; Odersky, Martin. Decrypting Local Type Inference https://infoscience.epfl.ch/record/214757

    If you want e to compile you can specify T

    val e: Unit = C.asInstanceOf[C.type{type T = Int}]{println(1);2}
    
    0 讨论(0)
提交回复
热议问题