Last active
December 10, 2015 01:38
-
-
Save ktoso/4360893 to your computer and use it in GitHub Desktop.
Blogpost about value classes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Meter(val n: Int) extends AnyVal | |
def traveled(m: Meter) = | |
s"You traveled ${m.n} meters!" | |
val meters = new Meter(34) | |
traveled(meters) should equal ("You traveled 20 meters!") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Meter(val n: Int) extends AnyVal { | |
def traveled = s"You traveled ${n} meters!" | |
} | |
val meters = new Meter(34) | |
meters.traveled should equal ("You traveled 20 meters!") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// [meters.traveled] was compiled into: | |
22: invokevirtual #37; //Method Meter$.traveled$extension:(I)Ljava/lang/String; | |
// so it's calling a method on the companion object, which takes an [int] | |
// still no Meter in sight here... | |
// :javap -v Meter | |
// does Meter even exist, if I'd want to use it explicitly? | |
public java.lang.String traveled(); | |
7: invokevirtual #26; //Method Meter$.traveled$extension:(I)Ljava/lang/String; | |
// yes it exists, and is delegating all the work to the companion object | |
// :javap -v Meter$ // the [companion object]! | |
public final java.lang.String traveled$extension(int); | |
// which contains the actual implementation of traveled | |
// notice the $extension suffix marking that it's a generated method. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
implicit class AwesomeString(val s: String) { | |
def awesome_! = s + "! Awesome!" | |
} | |
// an [implicit final def AwesomeString(String): AwesomeString] is generated for us automatically | |
"Scala".awesome_! | |
// 3: ldc #21; //String Scala vvvvvvvvvvvvvvvvvvvvvvvvvv | |
// 5: invokevirtual #25; //Method AwesomeString:(Ljava/lang/String;)LTesting$AwesomeString; << returns boxed! | |
// 8: invokevirtual #30; //Method AwesomeString.awesome_$bang:()Ljava/lang/String; | |
// Called: AwesomeString.awesome_$bang:()Ljava/lang/String; | |
// This impl. takes the `s` from the AwesomeString's instance! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
implicit class AwesomeString2(val s: String) extends AnyVal { | |
def awesome_! = s + "! Awesome!" | |
} | |
"Scala".awesome_! | |
// 18: ldc #35; //String Scala vvvvvvvvvvvvvvvvvvvvv | |
// 20: invokevirtual #39; //Method AwesomeString2:(Ljava/lang/String;)Ljava/lang/String; << returns not boxed! | |
// 23: invokevirtual #42; //Method AwesomeString2$.awesome_$bang$extension:(Ljava/lang/String;)Ljava/lang/String; | |
// vvvvvvvvvvvvvvvvvvv | |
// Called: AwesomeString2.awesome_$bang:(Ljava/lang/String;)Ljava/lang/String; | |
// as you can see the method gets the string passed in right away |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait AwesomeStringImplicits { | |
// boilerplate... | |
implicit def asAwesomeString(s: String) = | |
new AwesomeString(s) | |
class AwesomeString(s: String) { | |
def awesome_! = s + "! Awesome!" | |
} | |
} | |
object Main extends App | |
with AwesomeStringImplicits { | |
"Scala".awesome_! | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// def traveled(m: Meter) was compiled as: | |
public java.lang.String traveled(int); // where's my Meter?! | |
// val meters = new Meter(34) | |
0: bipush 34 // ok that's the int... | |
2: istore_1 // that's all, no Meter in sight! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment