Scala
A Java jövője
- JVM-en fut
- Típusos
- Teljesen objektum orientált
- Funkcionális programozás támogatása
- Minta illesztés
- Többszörös öröklődés (Mixin)
- Implicit konverzió
- Actor alapú konkurencia kezelés
- Ruby szerű szintaxis
és még sok minden
- Egyszerre használható Java és Scala
ugyanabban a projektben
- Használhatók a meglévő Java libek
- IDE támogatás
- Ha valami nem megy, csináld Jávában
//Minden érték egy objektum
1
.
toString
//Minden művelet egy metódus hívás
1
+
2
+
3
->
(
1
).+(
2
).+(
3
)
// . és ( ) elhagyható
"abc"
charAt
1
->
"abc"
.
charAt
(
1
)
//Java
public class HelloWorld {
public static void main(String[] args) { String message = "Hello World"; System.out.println(message); } } //Scala object HelloWorld { def main(args:Array[String]):Unit = { val message = "Hello World"
println(message) }
}
object
Hello
{
def
world
=
"Hello World"
}
Hello.world
Singleton támogatás
//Hello$.class
importscala.ScalaObject;
publicfinalclassHello$implementsScalaObject{
privateHello$(){MODULE$= this;}
publicStringworld(){return"Hello World";}
publicstaticfinal MODULE$;
static { new(); } } //Hello.class importscala.reflect.ScalaSignature; @ScalaSignature(bytes="...removed...")
publicfinalclassHello {
publicstaticfinalStringworld()
{
returnHello..MODULE$.world();
} }
class SimpleVal {
val finalValue: String = "hi"
var simpleVariable: String = ""
}
import scala.ScalaObject;
import scala.reflect.ScalaSignature;
@ScalaSignature(bytes = "...removed...") public class SimpleVal
implements ScalaObject {
private final String finalValue = "hi"; private String simpleVariable = "";
public String finalValue() { return this.finalValue; }
public String simpleVariable() { return this.simpleVariable; }
public void simpleVariable_$eq(String paramString) {
this.simpleVariable = paramString; }
//Java
public class Person {
private final String name; private final int age;
public Person(String name,int age) { this.name = name;
this.age = age; }
public String getName() { return name;
}
public int getAge() { return age; }
}
//Scala
class Person(val name:String, val age:Int)
//Java
publicclassPerson{
privateStringname;
privateintage;
publicPerson(Stringname,intage){
this.name= name;
this.age= age; }
publicStringgetName(){
returnname; }
publicintsetName(Stringname){
this.name=name; }
publicStringgetAge(){
returnage; }
publicintsetAge(Stringage){
this.age=age; } } //Scala importreflect.BeanProperty classPerson{ @BeanProperty varname:String=_ @BeanProperty varage:Int=_ }
val
sum
=
1
+
2
+
3
val
nums
=
List
(1,
2,
3)
val
map
=
Map
(
"abc"
->
List
(1,
2,
3))
val
sum
: Int
=
1
+
2
+
3
val
nums
:
List[Int]
=
List
(1,
2,
3)
val
map
:
Map[String, List[Int]]
=
Map
(
"abc"
->
List
(1,
2,
3))
object BigDuck {
def quack(value: String) = { value.toUpperCase
} }
object SmallDuck {
def quack(value: String) = { value.toLowerCase
} }
object IamNotReallyADuck { def quack(value: String) = { "prrrrrp"
} }
Duck typing
def quacker(duck: {def quack(value: String): String}) { println (duck.quack("Quack"))
}
quacker(BigDuck) quacker(SmallDuck)
quacker(IamNotReallyADuck)
def
transaction(function
:
=>
Any
)
: Any
=
{
//...
}
transaction
{
//here your database code
}
def
measure[T](func:
=>
T):T
=
{
val
start
=
System.nanoTime()
val
result
=
func
val
elapsed
=
System.nanoTime()
-
start
println(
"The execution of this call took: %s ns"
.format(elapsed))
result
}
def
myCallback
=
{
Thread
.sleep(1000)
"I'm a callback"
}
val
result
=
measure(myCallback)
>
The
execution
of
this
call
took
:
1002449000
ns
import
org.scalatest.FunSuite
import
scala.collection.mutable.Stack
class
ExampleSuite
extends
FunSuite
{
test(
"pop is invoked on an empty stack"
)
{
val
emptyStack
=
new
Stack[Int]
intercept[NoSuchElementException]
{
emptyStack.pop()
}
assert(emptyStack.isEmpty)
}
}
High-order funkciók
- Hasonló a Java switch-hez
- Bármilyen típusú adatra használható
- Első találat szabály
def matchTest(x: Any): Any = x match { case 1 | 2 | 3 => "one"
case "two" => 2
case a: Int if (a > 100) => a - 3
case b: Int => b + 3
case _ => "None of above"
}
def div(a:Int)(b:Int):Option[Int] = if (b <= 0) None
else if (a < b) Some(0)
else Some(1 + div(a - b)(b).get)
div(25)(5) // => Some(5) div(150)(2) // => Some(75) div(13)(4) // => Some(3) div(13)(0) // => None div(25)(-5) // => None
Option
div(13)(0) match {case Some(x) => println(x)
case None => println("Problems") }
// => prints "Problems" div(25)(5) match {
case Some(x) => println(x)
case None => println("Problems") }
implicit
def
doubleToInt(d:
Double)
=
d.toInt
val
x:
Int
=
42.0
//Java
public
<T>
void
javaNoManifest(Class<T>
clazz)
{
//...
}
//Scala
def
manifestTest[T](implicit
m:Manifest[T])
=
{
m.runtimeClass
}
class Complex(val real : Double, val imag : Double) {
def +(that: Complex) =
new Complex(this.real + that.real, this.imag + that.imag)
def -(that: Complex) =
new Complex(this.real - that.real, this.imag - that.imag) override def toString = real + " + " + imag + "i"
}
object Complex {
def main(args : Array[String]) : Unit = { var a = new Complex(4.0,5.0)
var b = new Complex(2.0,3.0) println(a) // 4.0 + 5.0i println(a + b) // 6.0 + 8.0i println(a - b) // 2.0 + 2.0i } }
Operátor túlterhelés
//Hasonló a Java interfacehez
trait
Language
{
val
name
:String
//De tartalmazhat implementációt is
override def
toString
=
name
}
trait
JVM
{
override
def
toString
=
super
.toString
+
" runs on JVM"
}
trait
Static
{
override
def
toString
=
super
.toString
+
" is Static"
}
//A trait-ek összefűzhetők (a sorrend számít!)
class
Scala
extends
Language
with
JVM
with
Static
{
val
name=
"Scala"
}
println(
new
Scala
())
// -> "Scala runs on JVM is Static"
trait
Quacking
{
def
quack()
=
{
println(
"Quack quack quack!"
)
}
}
class
Duck
{
val
version
=
"ACME Inc. Generic Duck v1.0"
}
val
aDuck
=
new
Duck
with
Quacking
aDuck.quack()
abstract class Term
case class Var(name: String) extends Term
case class Fun(arg: String, body: Term) extends Term
case class App(f: Term, v: Term) extends Term
val x1 = Var("x") val x2 = Var("x") val y1 = Var("y")
println("" + x1 + " == " + x2 + " => " + (x1 == x2)) println("" + x1 + " == " + y1 + " => " + (x1 == y1))
Var(x) == Var(x) => true
Var(x) == Var(y) => false
Case Class
def printTerm(term: Term) { term match { case Var(n) => print(n) case Fun(x, b) => print("^" + x + ".") printTerm(b) case App(f, v) => Console.print("(") printTerm(f) print(" ") printTerm(v) print(")") } }
class Companion {
def hello() { println("Hello (class)") } // [1] }
object Companion {
def hallo() { println("Hallo (object)") } // [2] def hello() { println("Hello (object)") } // [3] }
public class TestCompanion {
public static void main(String[] args) { new Companion().hello(); // [1]
Companion.hallo(); // [2] (static)
Companion$.MODULE$.hello(); // [3] (static) }
}
val someXMLInAString = """ <sammich> <bread>wheat</bread> <meat>salami</meat> <condiments> <condiment expired="true">mayo</condiment> <condiment expired="false">mustard</condiment> </condiments> </sammich> """ import scala.xml._ val someXML = <sammich> <bread>wheat</bread> <meat>salami</meat> <condiments>
<condiment expired="true">mayo</condiment> <condiment expired="false">mustard</condiment> </condiments>
</sammich>