Last Updated : 2009/5/31 (2006/7/4 より執筆開始)
asato <asatohan at gmail.com>
内容に関するコメント(感想、提案、書き間違いの指摘)は歓迎します。
概要
実験環境
例
例 - 基本 - 1
object Main {
def main(args: Array[String]) {
Console.println("Hello")
}
}
実行結果:
HelloConsoleは省略できます。
object Main {
def main(args: Array[String]) {
println("Hello")
}
}
例 - 基本 - 2
object Main extends Application {
println("Hello")
}
実行結果:
Hello
例 - クラス - 1
class Person(personName : String) {
var name : String = personName
def getName() : String = name;
}
object Main {
def main(args : Array[String]) {
val person = new Person("aaa");
println( person.getName() ); // aaa
}
}
実行結果:
aaa
例 - クラス - 2
class Person(personName : String) {
var name : String = personName
def setName(personName : String) {
name = personName
}
def getName() : String = name;
}
object Main {
def main(args : Array[String]) {
val person = new Person("aaa");
println( person.getName() ); // aaa
person.setName("xxx");
println( person.getName() ); // xxx
}
}
実行結果:
aaa xxx
例 - クラス - override
class Person(personName : String) {
var name : String = personName
def getName() : String = name;
override def toString(): String = "name = " + name
}
object Main {
def main(args : Array[String]) {
val person = new Person("aaa");
println( person ) // "name = aaa"
}
}
実行結果:
name = aaa
例 - 抽象クラス
abstract class Shape {
def draw
}
class Rectangle extends Shape {
def draw = println("rectangle")
}
class Circle extends Shape {
def draw = println("circle")
}
object Main extends Application {
def draw(s : Shape) = s.draw
val s1 = new Circle
val s2 = new Rectangle
draw(s1)
draw(s2)
}
実行結果:
circle rectangle
例 - Trait - 1
object Main extends Application {
trait MyTrait {
def method {
println("MyTrait.method")
}
}
class MyClass extends MyTrait {
}
val my = new MyClass
my.method
}
実行結果:
MyTrait.method
例 - Trait - 2
object Main extends Application {
trait MyTrait {
def method {
println("MyTrait.method")
}
}
class MyClass {
}
val my = new MyClass with MyTrait
my.method
}
実行結果:
MyTrait.method
例 - Trait - 3
object Main extends Application {
trait MyTraitA {
def methodA {
println("MyTraitA.methodA")
}
}
trait MyTraitB {
def methodB {
println("MyTraitB.methodB")
}
}
class MyClass extends MyTraitA with MyTraitB {
}
val my = new MyClass
my.methodA
my.methodB
}
実行結果:
MyTraitA.methodA MyTraitB.methodB
例 - Trait - 4
object Main extends Application {
trait MyTraitA {
def methodA {
println("MyTraitA.methodA")
}
}
trait MyTraitB {
def methodB {
println("MyTraitB.methodB")
}
}
class MyClass {
}
val my = new MyClass with MyTraitA with MyTraitB
my.methodA
my.methodB
}
実行結果:
MyTraitA.methodA MyTraitB.methodB
例 - Trait - 5
object Main extends Application {
class MySuperClass {
def superMethod {
println("MySuperClass.MySuperClass")
}
}
trait MyTrait {
def traitMethod {
println("MyTrait.traitMethod")
}
}
class MyClass extends MySuperClass with MyTrait {
}
val my = new MyClass
my.superMethod
my.traitMethod
}
実行結果:
MySuperClass.MySuperClass MyTrait.traitMethod
例 - Trait - 6
object Main extends Application {
abstract class MyAbstractClass {
def method() {
println("MyAbstractClass.method")
}
}
class MySuperClass extends MyAbstractClass {
override def method() {
println("MySuperClass.method")
}
}
trait MyTrait extends MyAbstractClass {
override def method {
println("MyTrait.method - before super.method")
super.method
println("MyTrait.method - after super.method")
}
}
class MyClass extends MySuperClass with MyTrait {
}
val my = new MyClass
my.method
}
実行結果:
MyTrait.method - before super.method MySuperClass.method MyTrait.method - after super.method"MyAbstractClass.method" が表示されているのではないことに注意。
例 - Trait - 7
object Main extends Application {
abstract class MyAbstractClass {
def method();
}
trait MyTrait extends MyAbstractClass {
def loggedMethod {
println("MyTraitA.method - before super.method")
method
println("MyTraitA.method - after super.method")
}
}
class MyClass extends MyAbstractClass with MyTrait {
def method() {
println("MyClass.method")
}
}
val my = new MyClass
my.loggedMethod
}
実行結果:
MyTraitA.method - before super.method MyClass.method MyTraitA.method - after super.method
例 - Trait - 8
object Main extends Application {
abstract class MyAbstractClass {
def method() {
println("MyAbstractClass.method")
}
}
trait MyTraitA extends MyAbstractClass {
override def method {
println("MyTraitA.method - before super.method")
super.method
println("MyTraitA.method - after super.method")
}
}
trait MyTraitB extends MyAbstractClass {
override def method {
println("MyTraitB.method - before super.method")
super.method
println("MyTraitB.method - after super.method")
}
}
class MyClass extends MyAbstractClass {
}
val myA = new MyClass with MyTraitA
myA.method
println()
val myB = new MyClass with MyTraitB
myB.method
println()
val myAB = new MyClass with MyTraitA with MyTraitB
myAB.method
}
実行結果:
MyTraitA.method - before super.method MyAbstractClass.method MyTraitA.method - after super.method MyTraitB.method - before super.method MyAbstractClass.method MyTraitB.method - after super.method MyTraitB.method - before super.method MyTraitA.method - before super.method MyAbstractClass.method MyTraitA.method - after super.method MyTraitB.method - after super.method
例 - Case Classes - 1
object Main extends Application {
case class MyCaseClass
def print(c : MyCaseClass) {
println(c)
}
print( MyCaseClass() ) // new がいらないことに注意
}
実行結果:
MyCaseClass()
例 - Case Classes - 2
object Main extends Application {
case class MyCaseClass(s: String)
val my = MyCaseClass("aaa")
println(my.s)
}
実行結果:
aaa
例 - Case Classes - 3 - Pattern Matching
object Main extends Application {
abstract class Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
def eval(e: Expr): Int = e match {
case Number(x) => x
case Sum(l, r) => eval(l) + eval(r)
}
val e = Sum( Number(1), Number(2) )
val v = eval( e ) // もしくは val v = eval( Sum( Number(1), Number(2) ) )
println(v) // 3
}
実行結果:
3
例 - Generic Types and Methods - 1
object Main extends Application {
class Container[A] {
def print(a: A) = println(a)
}
val c1 = new Container[String]
c1.print("aaa")
// c1.print(1) コンパイルエラー
val c2 = new Container[Int]
// c2.print("aaa") コンパイルエラー
c2.print(1)
}
実行結果:
aaa 1
例 - Generic Types and Methods - 2
object Main extends Application {
abstract class MyAbstractClass {
def print
}
class MyClassA extends MyAbstractClass {
def print = println("MyClassA")
}
class MyClassB extends MyAbstractClass {
def print = println("MyClassB")
}
class Container[My <: MyAbstractClass] {
def print(my: My) = my.print
}
// val c = new Container[String] コンパイルエラー
val c1 = new Container[MyAbstractClass]
c1.print(new MyClassA)
c1.print(new MyClassB)
val c2 = new Container[MyClassA]
c2.print(new MyClassA)
// c2.print(new MyClassB) コンパイルエラー
}
実行結果:
MyClassA MyClassB MyClassA
例 - Generic Types and Methods - 3 - Polymorphic Methods
object Main extends Application {
def print[A](a1: A, a2: A) = println(a1 + ", " + a2)
print[String]("a", "b")
print[Int](1, 2)
// print[Int](1, "b") コンパイルエラー
}
実行結果:
a, b 1, 2
例 - Generic Types and Methods - 4 - variance annotations
object Main extends Application {
class Cell[+T](data: T) {
def get = data
}
def print(c: Cell[Any]) = println(c.get)
val c = new Cell[Int](1)
print(c)
}
実行結果:
1 avariance annotationを使わない場合:
object Main extends Application {
class Cell[T](data: T) {
def get = data
}
def print(c: Cell[Any]) = println(c.get)
val c = new Cell[Int](1)
print(c) // コンパイルエラー
}
例 - Pattern Matching - 1
object Main {
def main(args : Array[String]) {
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
println( matchTest(1) ) // one
println( matchTest(2) ) // two
println( matchTest(3) ) // many
println( matchTest(4) ) // many
}
}
実行結果:
one two many many関数を使わずに直接的に:
object Main extends Application {
val n = 1
n match {
case 1 => println("one")
case 2 => println("two")
case _ => println("many")
}
}
実行結果:
one
例 - Pattern Matching - 2
object Main extends Application {
class MyClassA {
def methodA() {
println("MyClassA.methodA()")
}
}
class MyClassB {
def methodB() {
println("MyClassB.methodB()")
}
}
def matchTest(my: AnyRef) = my match {
case a: MyClassA => a.methodA
case b: MyClassB => b.methodB
}
val my1 = new MyClassA
val my2 = new MyClassB
matchTest(my1)
matchTest(my2)
}
実行結果:
MyClassA.methodA() MyClassB.methodB()
例 - Pattern Matching - 3 - case class
object Main extends Application {
case class MyClass(var name: String)
def matchTest(my: AnyRef) = my match {
case MyClass(name) => println(name)
}
val my = new MyClass("aaa")
matchTest(my)
}
実行結果:
aaa
例 - Pattern Matching - 4 - unapply
object Main extends Application {
class MyClass(val _s: String)
{
def unapply(s: String): Option[String] = {
println("unapply: " + s)
if (_s == s) Some(_s + _s) else None
}
}
def matchTest(s: String, my: MyClass) = s match {
case my(x) => println("match true: " + x)
case _ => println("match false: " + s)
}
val my = new MyClass("a");
matchTest("a", my)
matchTest("b", my)
}
実行結果:
unapply: a match true: aa unapply: b match false: b
例 - Pattern Matching - 5
object Main extends Application {
1 match {
case n@1 => println("n=" + n)
}
}
実行結果:
n=1
例 - Pattern Matching - 6
object Main extends Application {
1 match {
case x => println("x=" + x)
}
}
実行結果:
x=1
例 - Pattern Matching - 7
object Main extends Application {
def m(x: Int, y: Int) = {
x match {
case `y` => println("x == y: " + x + " == " + y)
case _ => println("x != y: " + x + " != " + y)
}
}
m(1, 1) // "x == y: 1 == 1"
m(1, 2) // "x != y: 1 != 2"
}
実行結果:
x == y: 1 == 1 x != y: 1 != 2
例 - Pattern Matching - 8 - pattern guards
object Main extends Application {
def testMatch(o: Any) = {
o match {
case n: Int if n == 1 => println("n==1")
case s: String if s == "a" => println("s==a")
case _ => println("_")
}
}
testMatch(1) // "n==1"
testMatch(2) // "_"
testMatch("a") // "s==a"
testMatch("b") // "_"
}
実行結果:
n==1 _ s==a _
例 - Method Values - 1
object Main extends Application {
class StringPrinter {
def print(s: String) = println(s)
}
val printer = new StringPrinter
val print = printer.print _
print("aaa")
}
実行結果:aaa
例 - Higher-Order Functions - 1
object Main extends Application {
def decorate(s: String): String = { // String => String
"***" + s + "***"
}
def print(s: String, f: String => String) {
println( f(s) )
}
print("aaa", decorate) // ***aaa***
print("bbb", decorate) // ***bbb***
}
実行結果:
***aaa*** ***bbb***例:
object Main extends Application {
def decorate1(s: String) : String = {
"[[[" + s + "]]]";
}
def decorate2(s: String) : String = {
"***" + s + "***";
}
def print(s: String, f: String => String) {
println( f(s) );
}
print("aaa", decorate1); // [[[aaa]]]
print("aaa", decorate2); // ***aaa***
}
実行結果:
[[[aaa]]] ***aaa***
例 - Higher-Order Functions - 2
object Main extends Application {
def decorated(d: String): String => String = {
def decorate(s: String): String = {
d + s + d
}
decorate
}
val f = decorated("***")
println( f("aaa") )
println( f("bbb") )
}
実行結果:
***aaa*** ***bbb***
例 - Anonymous Function Syntax - 1
object Main extends Application {
val f = () => println("Hello")
f()
}
実行結果:
Hello
例 - Anonymous Function Syntax - 2
object Main extends Application {
val f1 = (x : int) => println(x)
val f2 = (x : int, y : int) => println(x + ", " + y)
f1(10)
f2(10, 20)
}
実行結果:
10 10, 20
例 - Anonymous Function Syntax - 3
object Main extends Application {
val f = (_ : int) + 1
println( f(1) )
}
実行結果:
1例:
object Main extends Application {
def print(i: int, f: int => int ) {
println( f(i) )
}
print(1, _ + 1)
}
実行結果:
2
例 - Anonymous Function Syntax - 4
object Main extends Application {
val f = println( _: String )
f("aaa")
}
実行結果:
aaa
例 - Anonymous Function Syntax - 5
object Main extends Application {
class Person(name : String) {
def getName() = name
}
val f = (_: Person).getName
println( f(new Person("aaa")) )
println( f(new Person("bbb")) )
}
実行結果:
aaa bbb
例 - Currying
object Main extends Application {
def sum(i: Int) : Int => Int = {
def sumF(j: Int) : Int = {
i + j
}
sumF
}
val sumInts = sum(1)
println( sumInts(2) ) // 3
実行結果:
3短いバージョン:
object Main extends Application {
def sum(i: Int)(j: Int) : Int = {
i + j
}
val sumInts = sum(1) _ // "_" に注意
println( sumInts(2) ) // 3
}
実行結果:
3
参考
例 - Currying - Function.curried
object Main extends Application {
def sum(i: Int, j: Int) : Int = {
i + j
}
val curriedSum = Function.curried(sum _)
println(curriedSum(1)(2)) // 3
}
実行結果:
3
例 - Currying - Function.uncurried
object Main extends Application {
def sum(i: Int)(j: Int) : Int = {
i + j
}
val curriedSum = Function.uncurried(sum _)
println(curriedSum(1, 2))
}
実行結果:
3
例 - Currying - 自分でやる - 1
object Main extends Application {
def sum(i: Int, j: Int) : Int = {
i + j
}
val curriedSum = (x: Int) => (y: Int) => sum(x, y)
println(curriedSum(1)(2))
}
実行結果:
3
例 - Currying - 自分でやる - 2
object Main extends Application {
def sum(i: Int)(j: Int) : Int = {
i + j
}
val uncurriedSum = (x: Int, y: Int) => sum(x)(y)
println(uncurriedSum(1, 2))
}
実行結果:
3
例 - By-Name Parameters - 1
object Main extends Application {
def print(s: String) {
println(s)
}
def call(proc: => Unit) {
println("before call")
proc
println("after call")
}
call( print("aaa") )
println()
call( { print("aaa"); print("bbb") } )
}
実行結果:
before call aaa after call before call aaa bbb after call
例 - By-Name Parameters - 2
object Main extends Application {
def print(s: String) {
println(s)
}
def call(proc: => Unit) {
println("before call")
proc
println("after call")
}
call { print("aaa") }
println()
call {
print("aaa")
print("bbb")
}
}
実行結果:
before call aaa after call before call aaa bbb after call
例 - By-Name Parameters - 3
object Main extends Application {
def get1: Int = {
println("get1")
1
}
def get2: Int = {
println("get2")
2
}
def call(e: => Int) {
println("before call")
println(e) // 3
println("after call")
}
call { get1 + get2 }
}
実行結果:
before call get1 get2 3 after call
例 - By-Name Parameters - 4
object Main extends Application {
def printOrNot(num: => int)(cond: => Boolean): Unit =
if (cond) {
println(num)
}
printOrNot(1 + 2)(true)
printOrNot(1 + 2)(false)
}
実行結果:
3
例 - Repeated Parameters
object Main extends Application {
def printSum(args: Int*) {
var result = 0
for (arg <- args.elements) result += arg
println(result)
}
printSum()
printSum(1, 2)
printSum(1, 2, 3)
}
実行結果:0 3 6Java バージョン:
public class Main {
public static void main(String[] args) {
printSum();
printSum(1, 2);
printSum(1, 2, 3);
}
private static void printSum(int... args) {
int result = 0;
for(int arg : args) {
result += arg;
}
System.out.println(result);
}
}
例 - By-Name Parameters - 5
object Main extends Application {
def whileLoop(cond: => Boolean)(body: => Unit): Unit =
if (cond) {
body
whileLoop(cond)(body)
}
var i = 10
whileLoop (i > 0) {
println(i)
i = i - 1
}
}
実行結果:
5 4 3 2 1
例 - Implicit Parameters - 1
object Main extends Application {
abstract class MyImplicit {
def print(i: int) {
println("*** " + i + " ***")
}
}
implicit object MyImplicit extends MyImplicit
def print(i: int)(implicit my: MyImplicit) {
my.print(i)
}
print(1)
}
実行結果:
*** 1 ***
例 - Implicit Parameters - 2
object Main extends Application {
abstract class MyImplicit[A] {
def print(a: A)
}
implicit object MyImplicitInt extends MyImplicit[Int] {
def print(i: Int) {
println("int: " + i)
}
}
implicit object MyImplicitString extends MyImplicit[String] {
def print(s: String) {
println("String: " + s)
}
}
def print[A](a: A)(implicit my: MyImplicit[A]) {
my.print(a)
}
print(1) // int: 1
print("aaa") // String: aaa
}
実行結果:
int: 1 String: aaa
例 - Implicit Conversions
object Main extends Application {
class Person(val name: String)
implicit def string2Person(name: String): Person = new Person(name);
val p = "aaa";
println( p.name )
}
実行結果:
aaa
例 - View Bounds - 1
object Main extends Application {
class MyClass
def viewTest[MyClass <% Int](my: MyClass) { // MyClass は Int に変換可能
println("execute viewTest")
val n = my + 1
println(n)
}
implicit def my2int(my: MyClass): Int = {
println("execute my2int")
1
}
viewTest(new MyClass)
}
実行結果:
execute viewTest execute my2int 2例:
object Main extends Application {
class MyClass
def viewTest[MyClass <% Int](my: MyClass) {
println("execute viewTest")
val n = my + 1
println(n)
}
def test {
implicit def my2int(my: MyClass): Int = {
println("execute my2int")
1
}
viewTest(new MyClass) // MyClassからIntに変換可能
}
test
viewTest(new MyClass) // MyClassからIntに変換できないのでコンパイルエラー
}
例 - View Bounds - 2
object Main extends Application {
def viewTest[T <% Int](t: T) {
println("execute viewTest")
val n = t + 1
println(n)
}
class MyClassA
class MyClassB
implicit def myA2int(myA: MyClassA): Int = {
println("execute myA2int")
1
}
implicit def myB2int(myB: MyClassB): Int = {
println("execute myB2int")
2
}
viewTest( new MyClassA )
viewTest( new MyClassB )
}
実行結果:
execute viewTest execute myA2int 2 execute viewTest execute myB2int 3
例 - View Bounds - 3
object Main extends Application {
class MyClass
def viewTest[T2, T1 <% T2](t1: T1, t2: T2) {
val t: T2 = t1
println(t)
}
implicit def my2int(my: MyClass): Int = {
1
}
implicit def my2string(myA: MyClass): String = {
"a"
}
viewTest(new MyClass, 1)
viewTest(new MyClass, "a")
}
実行結果:
1 a
例 - Type Declarations and Type Aliases - 1
object Main extends Application {
class MyClass {
type S = String
}
val s1: MyClass#S = "aaa"
// val s2: MyClass#S = 111 コンパイルエラー
}
例 - Type Declarations and Type Aliases - 2
object Main extends Application {
class MyClass {
type MyList[T] = List[T]
}
val list1: MyClass#MyList[Int] = List(1, 2, 3)
// val list2: MyClass#MyList[String] = List(1, 2, 3) コンパイルエラー
}
例 - Type Declarations and Type Aliases - 3
object Main extends Application {
class MyClass {
type Pair[T1, T2] = Tuple2[T1, T2]
}
val pair1: MyClass#Pair[Int, String] = (1, "aaa")
// val pair2: MyClass#Pair[Int, Int] = (1, "aaa") コンパイルエラー
}
例 - Type Declarations and Type Aliases - 4
object Main extends Application {
class MyClass {
type %[T1, T2] = Tuple2[T1, T2]
}
val m = new MyClass
import m._
val pair: Int%String = (1, "aaa")
}
例 - Type Declarations and Type Aliases - 5
object Main extends Application {
abstract class MyAbstractClass {
type MyType
def m(t: MyType) = println(t)
}
class MyClass extends MyAbstractClass {
type MyType = String
}
new MyClass().m("a")
// new MyClass().m(1) コンパイルエラー
}
実行結果:a
例 - Type Declarations and Type Aliases - 6
object Main extends Application {
abstract class AbstractComponent {
type CompType
}
class ComponentA extends AbstractComponent {
type CompType = String
}
class ComponentB extends AbstractComponent {
type CompType = Int
}
class MyClass[T <: AbstractComponent] {
type MyType = T#CompType
def m(my: MyType) = println(my)
}
val my1 = new MyClass[ComponentA]
my1.m("a")
// my1.m(1) コンパイルエラー
val my2 = new MyClass[ComponentB]
// my2.m("a") コンパイルエラー
my2.m(1)
}
実行結果:a 1
例 - Structural Types - 1
object Main extends Application {
class Person(name: String) {
def getName: String = name
}
def printName(f: { def getName: String }) { println(f.getName) }
printName( new Person("aaa") )
}
実行結果:aaa
例 - Structural Types - 2
object Main extends Application {
class Person(name: String) {
def getName: String = name
}
type Name = { def getName: String }
def printName(f: Name) { println(f.getName) }
printName( new Person("aaa") )
}
実行結果:aaa
例 - Structural Instance Creation Expression - 1
object Main extends Application {
val o = new { def print = println("xxx") }
o.print
}
実行結果:
xxxJava との比較:
public class Main {
public static void main(String[] args) {
new Object() {
public void print() {
System.out.println("xxx");
}
}.print();
}
}
次のようにはできません。
public class Main {
public static void main(String[] args) {
Object o = new Object() {
public void print() {
System.out.println("xxx");
}
};
o.print(); // コンパイルエラー。Object クラスに print メソッドはない
}
}
例 - Structural Instance Creation Expression - 2
object Main extends Application {
def create = new { def print = println("xxx") }
create.print
}
実行結果:
xxxJava との比較:
public class Main {
interface Printer {
public void print();
}
public static Printer create() {
return new Printer() {
public void print() {
System.out.println("xxx");
}
};
}
public static void main(String[] args) {
create().print();
}
}
例 - Self Types - 1
object Main extends Application {
trait MyTraitA {
def print = println("MyTraitA.print")
}
trait MyTrait {
this: MyTraitA =>
def callPrint = {
this.print
}
}
val my = new MyTrait with MyTraitA
my.callPrint
}
実行結果:MyTraitA.print
例 - Self Types - 2
object Main extends Application {
trait MyTraitA {
def print = println("MyTraitA.print")
}
trait MyTraitB {
def print = println("MyTraitB.print")
}
trait MyTrait {
this: { def print } =>
def callPrint = {
this.print
}
}
val my1 = new MyTrait with MyTraitA
my1.callPrint
val my2 = new MyTrait with MyTraitB
my2.callPrint
}
実行結果:MyTraitA.print
例 - Self Types - 3
object Main extends Application {
trait Printer {
def print = println("Printer.print")
}
class PrinterClient {
def callPrint(p: Printer) = p.print
}
trait MyTrait {
this: Printer =>
def callClientPrint = {
new PrinterClient().callPrint(this)
}
}
class MyClass extends Printer;
val my = new MyClass with MyTrait
my.callClientPrint
}
実行結果:Printer.print
例 - this.type - 1
object Main extends Application {
class MyClass {
def getThis: this.type = this
def m = println("MyClass")
}
val my = new MyClass().getThis
my.m
}
実行結果:MyClass
例 - this.type - 2
object Main extends Application {
class MyClass {
def getThis: this.type = this
def m = println("MyClass")
}
class MySubClass extends MyClass {
def n = println("MySubClass")
}
val mySub = new MySubClass().getThis
mySub.n
}
実行結果:MySubClass
例 - this.type - 3
object Main extends Application {
class MyClass {
def getThis: this.type = new MyClass // コンパイルエラー
}
}
インタプリタ:
scala> object Main extends Application {
|
| class MyClass {
| def getThis: this.type = new MyClass
| }
| }
:7: error: type mismatch;
found : Main.MyClass
required: MyClass.this.type
def getThis: this.type = new MyClass
例 - this.type - 4
object Main extends Application {
class MyClass {
def setThis(t: this.type) = println(t)
}
val my1 = new MyClass
val my2 = new MyClass
my1.setThis( my1 )
my1.setThis( my2 ) // コンパイルエラー
}
例 - this.type - 5
object Main extends Application {
class MyClass {
def setThis(t: this.type) = println(t)
}
val my1 = new MyClass
val my2 = new MyClass
my1.setThis( my1 )
my1.setThis( my2 ) // コンパイルエラー
}
例 - this.type - 6 - Generic Type との組み合わせ
object Main extends Application {
class Container[T](val v: T)
class MyClass {
def createContainer = new Container[this.type](this)
def printContainer(c: Container[this.type]) = println(c.v)
}
val my1 = new MyClass
val my2 = new MyClass
val c1 = my1.createContainer
val c2 = my2.createContainer
my1.printContainer(c1)
my1.printContainer(c2) // コンパイルエラー
}
例 - onj.type - 1
object Main extends Application {
class MyClass
val my1 = new MyClass
val my2 = new MyClass
val my3: my1.type = my1
val my4: my1.type = my2 // コンパイルエラー
val my5: MyClass = my3
}
例 - onj.type - 2
object Main extends Application {
class MyClass
val my1 = new MyClass
val my2 = new MyClass
val my3: my1.type = my1
val my4: my1.type = my2.asInstanceOf[my1.type] // キャストOK
println(my3)
println(my4)
}
実行結果:test.obj_type.test02.Main$MyClass@dd20f6 test.obj_type.test02.Main$MyClass@19efb05
例 - onj.type - 3
object Main extends Application {
class MyClass(val mys: String) {
def print(s: mys.type) = println(s)
}
val my = new MyClass("aaa")
my.print(my.mys)
my.print("bbb") // コンパイルエラー
}
例 - apply method
object Main extends Application {
class MyClass {
def apply(i: int) = i;
}
val my = new MyClass
println( my(10) ); // println( my.apply(10) ) と同じ
}
実行結果:10
例 - List
object Main {
def main(args : Array[String]) {
val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
println( nums )
}
}
実行結果:
List(1, 2, 3, 4, 5, 6, 7, 8)
例 - Manifest - 1
object Main extends Application {
class MyClass[T](implicit val manifest: scala.reflect.Manifest[T])
println( new MyClass[String].manifest )
println( new MyClass[Int].manifest )
println
println( new MyClass[String].manifest.erasure )
println( new MyClass[Int].manifest.erasure )
}
実行結果:java.lang.String int class java.lang.String int
例 - Exception
package test.exception.test01;
object Main extends Application {
class MyException extends Exception
def m() {
throw new MyException
}
try {
m
} catch {
case e: MyException => println("Exception: " + e)
}
}
実行結果:Exception: test.exception.test01.Main$MyException
例 - Cast
object Main extends Application {
def test(any : Any) = {
val s = any.asInstanceOf[String]
println(s)
}
test("aaa")
test(100)
}
実行結果:
aaa Exception in thread "main" java.lang.ExceptionInInitializerError at test19.Main.main(Main.scala) Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at test19.Main$.test(Main.scala:6) at test19.Main$.(Main.scala:14) at test19.Main$. (Main.scala) ... 1 more
例 - classOf
object Main extends Application {
class MyClass
val clazz1 = classOf[MyClass]
val clazz2 = classOf[String]
println(clazz1)
println(clazz1.getClass())
println(clazz2)
println(clazz1.getClass())
}
実行結果:
class test51.Main$MyClass class java.lang.Class class java.lang.String class java.lang.Classインタプリタ:
scala> class MyClass defined class MyClass scala> val clazz1 = classOf[MyClass] clazz1: java.lang.Class[MyClass] = class MyClass scala> val clazz2 = classOf[String] clazz2: java.lang.Class[String] = class java.lang.String
例 - import - 1
package test.imp.test01.your
class YourClass {
}
package test.imp.test01.my;
import test.imp.test01.your.YourClass
object Main extends Application {
val your = new YourClass
println(your)
}
実行結果:
test.imp.test01.your.YourClass@a83b8a
例 - import - 2
package test.imp.test02.your
class YourClass {
}
package test.imp.test02.my
object Main extends Application {
def m() = {
import test.imp.test02.your.YourClass
val your = new YourClass
println(your)
}
m()
// val your = new YourClass // コンパイルエラー
// println(your)
}
実行結果:
test.imp.test02.your.YourClass@dd20f6
例 - import - 3
object Main extends Application {
class MyClass {
def method = println("MyClass.method")
}
val my = new MyClass
import my._
method
}
実行結果:
MyClass.method
例 - import - 4
object Main extends Application {
class MyClass {
class MyInnerClass {
def method = println("MyInnerClass.method")
}
}
val my = new MyClass
import my._
val myInner = new MyInnerClass
myInner.method
}
実行結果:
MyInnerClass.method
例 - その他 - JFrame
import javax.swing.JFrame
import javax.swing.JFrame._
object Main extends Application {
val f = new JFrame("My")
f.setSize(100, 100)
f.setDefaultCloseOperation(EXIT_ON_CLOSE)
f.setVisible(true)
}
実行結果:例 - Actor ライブラリ - 1
import scala.actors._
object Main extends Application {
class MyActor extends Actor {
def act() { // 抽象メソッドを実装
println("act - start")
var running = true
while(running) {
receive { // receive メソッド
case "end" =>
println("receive: end")
running = false
case msg: Any =>
println("receive: " + msg)
}
}
println("act - end")
}
}
val my = new MyActor
my.start
my ! "msg1" // ! メソッド は送信 (send) の意味
my ! "msg2"
my ! "end"
}
実行結果:
act - start receive: msg1 receive: msg2 receive: end act - end
例 - Parser Combinator ライブラリ - 1
import scala.util.parsing.combinator._
object MyParser extends RegexParsers {
def leftParent: Parser[Any] = '('
}
object Main extends Application {
import MyParser._
println( parseAll( leftParent, "(" ) )
println( parseAll( leftParent, "( " ) )
println( parseAll( leftParent, " ( " ) )
println( parseAll( leftParent, "((" ) )
}
実行結果:
[1.2] parsed: (
[1.3] parsed: (
[1.1] failure: `(' expected but found
(
^
[1.2] failure: string matching regex `\z' expected but `(' found
((
例 - Parser Combinator ライブラリ - 2
import scala.util.parsing.combinator._
object MyParser extends RegexParsers {
def leftParent: Parser[Any] = '('
}
object Main extends Application {
import MyParser._
parseAll( leftParent, "(" ) match {
case Success(_, _) => println("Success")
case Failure(_, _) => println("Failure")
}
parseAll( leftParent, ")" ) match {
case Success(_, _) => println("Success")
case Failure(_, _) => println("Failure")
}
}
実行結果:
Success Failure
例 - Parser Combinator ライブラリ - 3
object MyParser extends RegexParsers {
def parent: Parser[Any] = "(" | ")"
}
object Main extends Application {
import MyParser._
println( parseAll( parent, "(" ) )
println( parseAll( parent, ")" ) )
println( parseAll( parent, "()" ) )
}
実行結果:
[1.2] parsed: ( [1.2] parsed: ) [1.2] failure: string matching regex `\z' expected but `)' found () ^
例 - Parser Combinator ライブラリ - 4
import scala.util.parsing.combinator._
object MyParser extends JavaTokenParsers {
def parent: Parser[Any] = "(" ~ ident ~ ")"
}
object Main extends Application {
import MyParser._
println( parseAll( parent, "(aaa)" ) )
println( parseAll( parent, "( aaa )" ) )
println( parseAll( parent, "( aaabbb )" ) )
println( parseAll( parent, "( aaa ) ( bbb )" ) )
}
実行結果:
[1.6] parsed: (((~aaa)~))
[1.8] parsed: (((~aaa)~))
[1.11] parsed: (((~aaabbb)~))
[1.9] failure: string matching regex `\z' expected but ` ' found
( aaa ) ( bbb )
^
例 - Parser Combinator ライブラリ - 5
object MyParser extends JavaTokenParsers {
def parent2: Parser[Any] = rep(parent)
def parent: Parser[Any] = "(" ~ ident ~ ")"
}
object Main extends Application {
import MyParser._
println( parseAll( parent2, "( aaa )" ) )
println( parseAll( parent2, "(aaa) (bbb)" ) )
println( parseAll( parent2, "(aaa) (bbb) (ccc)" ) )
println( parseAll( parent2, "((aaa))" ) )
}
実行結果:
[1.8] parsed: List((((~aaa)~)))
[1.12] parsed: List((((~aaa)~)), (((~bbb)~)))
[1.18] parsed: List((((~aaa)~)), (((~bbb)~)), (((~ccc)~)))
[1.2] failure: string matching regex `[a-zA-Z_]\w*' expected but `(' found
((aaa))
^
例 - Parser Combinator ライブラリ - 6 - ^^ オペレータ
import scala.util.parsing.combinator._
object MyParser extends JavaTokenParsers {
def parent: Parser[Any] = "(" ~ ident ~ ")" ^^ { case "(" ~ ident ~ ")" => "(" + ident + ")"}
}
object Main extends Application {
import MyParser._
println( parseAll( parent, "(aaa)" ) )
println( parseAll( parent, "( aaa )" ) )
println( parseAll( parent, "( aaabbb )" ) )
}
実行結果:
[1.6] parsed: (aaa) [1.8] parsed: (aaa) [1.11] parsed: (aaabbb)
参考文献とリソース
更新履歴
todo