java使いのためのScala の勉強のための資料作り scalaって素晴らしい いろいろ1

http://d.hatena.ne.jp/nazoking/20100514/1273774142 の続き

細かいというか解説がいらないのいろいろ

すべてがオブジェクト

オブジェクト指向型言語javaにおいてObjectではないものがある。int,long,floatなど。

たとえば

1.toString()

コンパイルできない。

しかし! scalaでは「すべてがオブジェクト」なので、上のコードはなんの問題もなくコンパイルできる。javaではいろんなところでintとIntegerの変換をしてやる必要があるが、scalaではそれは全部コンパイラが面倒を見てくれる。

クラス階層はこんな感じ

Any
 +--AnyVal
 |  +-Int
 |  +-Byte
 |  +-:
 |
 +--AnyRef <=Object
    +- String
    +- 普通のクラス
    +- :

デフォルト値付き引数

scala2.8で引数のデフォルト値が定義できるようになった。phpjavascriptrubyでは当たり前の機能だがjavaではなかった。

void hoge(){
  hoge("Aの初期値");
}
void hoge(String a){
  hoge(a,"Bの初期値");
}
void hoge(String a,String b){
  // aとbを使ったなんかの処理
}

こんなコードは、scalaではこうかける。

def hoge(a:String="aの初期値", b:String="bの初期値")={
  // aとbを使ったなんかの処理
}

コードが1/3に!(というかjavaだと組み合わせの数だけ増えるし)

名前付き引数

def hoge(aaa:String,bbb:String):Unit={
	var (a , b) = (1,"hoge");
	println("a="+a);
	println("b="+b);
}
def huge():Unit={
	hoge(bbb="b",aaa="a");
}

わかりやすい!
ただ

var a:Stirng="aa";
hoge(a="bb")
println(a); // ←"aa"が表示される

みたいな……。まあどっちがどっち

デフォルト値付き引数と組み合わせるとさらに便利ですね。

def getHttp(url:String, method:String="POST", postData:String="", 
  addHeader:List[String]=Nil):String={
  // なんかhttpからとってくる関数
}

みたいな、どれが重要かよく分からないメソッドも簡単に。

import で別名

java.lang.Date と java.sql.Date の両方使いたいけど

import java.lang.Date;
import java.sql.Date;

って書くとコンパイルできないし、出来たらでどっち使ってるか分からないしムキー

import java.util.Date;
import java.sql.{Date => SQLDate}

override

あるAbstructHogeクラスをextendsしてhogeメソッド作ってたらいつの間にかAbstructHogeクラスがバージョンアップされてhogeメソッドが出来ていた!仕様が似ているようで違うのでバグがなかなか発見できない……

scalaではoverrideするときoverrideってつけないといけない。だから上記の事例ではコンパイルエラーになる。

javabean が簡単に書ける

scala

import scala.reflect._;
case class Hoge(){
  @BeanProperty var b:String=_;
}

とすると

public class Fuga {
	public static void main(String[] args) {
		Hoge a= new Hoge();
		a.setB("a");
		System.out.println(a.getB()); // "a" が表示
	}
}

Singletonの言語レベルサポート

Singletonが言語レベルである!

object Hoge{
}

とするとこのクラスが読み込まれた時点で生成される。

Generate Constractor using filds の言語レベルサポート

複数行文字列リテラル

val a="""
 hoge
 huga
""";

みたいな!

最後に ; がなくても動く

便利なんだろうかどうなんだろう。rubyとかjavascriptではとっくにそうなってて、まあ不便ではないです。

return が必要ない

最後の文の返す値が戻り値。Rubyと同じですね。

型宣言が出来るのでRubyみたいに「なんかswitch(rubyだとcase)のよくわかんないところでreturnしちゃって変なの返してて何が起こっているのか分からない」みたいな事態は少なそう……だけど完全には防げていないなぁ。

とはいえ便利ですよ。

複数の値を返すTuple

複数の値を返したい処理の時に、仕方ないのでちっちゃいクラスを作ってそいつに入れ込んで、受け取る側ではそのクラスで受け取って各プロパティーを云々みたいなしょりが、結構あるけどscalaなら

var (a , b) = (1,"hoge");
println("a="+a); // a=1
println("b="+b); // b=String

しかも型安全。

遅延評価

private hoge=null;
pulbic String hoge(){
  if(hoge==null){
    hoge= なんか時間がかかるけど常に同じなString取得処理();
  }
  return hoge;
}

を言語レベルでサポート

  lazy val hoge:String=なんか時間がかかるけど常に同じなString取得処理();

javaBeanサポート

/** hogeです **/
String hoge="なんか";
/** hogeです **/
public getHoge(){
  return hoge;
}
/** hogeです **/
public getHoge(String hoge){
  this.hoge=hoge;
}
↓scalaなら
>|scala|
/** hogeです **/
@BeanProperty var hoge:String="なんか";

コードが2/10に! しかもコメントに変更があっても一行だけ変えればいい。