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で引数のデフォルト値が定義できるようになった。phpやjavascriptやrubyでは当たり前の機能だが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 が簡単に書ける
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 の言語レベルサポート
最後に ; がなくても動く
便利なんだろうかどうなんだろう。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に! しかもコメントに変更があっても一行だけ変えればいい。