简体   繁体   中英

Single Abstract Method Equivalent to a Trait?

Consider this trait:

trait Foo {
  def m1(id : Int) : Try[String]
}

And an instance of this:

  val g : Foo = new Foo {
    override def m1(id: Int): Try[String] = Success("Good job")
  }

Intellij offered a suggestion that this could converted to a Single Abstract Method:

  val g : Foo = (id: Int) => Success("Good job")

Are these two equivalent and how?

Lets check what the scalac do for:

import scala.util.{Success, Try}

trait Foo {
  def m1(id : Int) : Try[String]
}

object MainClass {
  val g : Foo = new Foo {
    override def m1(id: Int): Try[String] = Success("Good job")
  }
}

run:

$ scalac -print src/main/scala/MainClass.scala

and output:

[[syntax trees at end of                   cleanup]] // MainClass.scala
package <empty> {
  abstract trait Foo extends Object {
    def m1(id: Int): scala.util.Try
  };
  object MainClass extends Object {
    private[this] val g: Foo = _;
    <stable> <accessor> def g(): Foo = MainClass.this.g;
    def <init>(): MainClass.type = {
      MainClass.super.<init>();
      MainClass.this.g = {
        new <$anon: Foo>()
      };
      ()
    }
  };
  final class anon$1 extends Object with Foo {
    override def m1(id: Int): scala.util.Try = new scala.util.Success("Good job");
    def <init>(): <$anon: Foo> = {
      anon$1.super.<init>();
      ()
    }
  }
}

And do the same steps for:

import scala.util.{Success, Try}

trait Foo {
  def m1(id : Int) : Try[String]
}

object MainClass {

  def main(args: Array[String]): Unit = {
    val g : Foo = (id: Int) => Success("Good job")
  }
}

run:

$ scalac -print src/main/scala/MainClass.scala

output:

[[syntax trees at end of                   cleanup]] // MainClass.scala
package <empty> {
  abstract trait Foo extends Object {
    def m1(id: Int): scala.util.Try
  };
  object MainClass extends Object {
    private[this] val g: Foo = _;
    <stable> <accessor> def g(): Foo = MainClass.this.g;
    final <artifact> private[this] def $anonfun$g$1(id: Int): scala.util.Try = new scala.util.Success("Good job");
    def <init>(): MainClass.type = {
      MainClass.super.<init>();
      MainClass.this.g = {
        ((id: Int) => MainClass.this.$anonfun$g$1(id))
      };
      ()
    }
  }
}

As you can see they are not the same for compiler.

In the first case, it is an anonymous object in second it is an anonymous function.

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