| Version 64 (modified by keisuken, 5 years ago) |
|---|
Scala-sandbox-docs
Scala-sandboxの文書ページです.
技術情報やライブラリの使い方,FAQ(Q&A)などがここに書かれます.
なお,このページとは別にScala-sandboxのトップページがあります.
技術情報
文法
- val
- valで定義した変数は、一度値を設定した後は更新することができません
(Javaのfinalのようなものです)。あくまで、更新できないのは変数の値で
であって、変数が指している先のオブジェクトを変更することは可能であることに
注意してください(この点もJavaのfinalと同じです)。
val a :Int = 10 a = 20 // エラー。valで定義した変数の値を更新することはできない val a = 10 // 変数の型は省略可能 val b:Array[Int] = Array(1, 2, 3) b(0) = 2 // OK。変数が指しているオブジェクト(配列)の内容は更新できる
- valで定義した変数は、一度値を設定した後は更新することができません
(Javaのfinalのようなものです)。あくまで、更新できないのは変数の値で
であって、変数が指している先のオブジェクトを変更することは可能であることに
注意してください(この点もJavaのfinalと同じです)。
- var
- varで定義した変数は、値を更新することができる変数になります
(Javaの通常の変数と同じ)。
var a :Int = 10 a = 20 // OK。 var a = 10 // 変数の型は省略可能
- varで定義した変数は、値を更新することができる変数になります
(Javaの通常の変数と同じ)。
- for
- for文は、Javaの拡張for文と同じように使えます
// 1から10まで1つずつ加算しながらループ for (i <- 1 to 10) { printf("{0} ", i) } > 1 2 3 4 5 6 7 8 9 10 // 0から9まで1つずつ加算しながらループ for (i <- 0 until 10) { printf("{0} ", i) } > 0 1 2 3 4 5 6 7 8 9 // Int型の配列でループ for (value <- Array(1, 2, 3, 4)) { printf("{0} ", value) } > 1 2 3 4 - 関数型言語でよく使われるmapやfilterにも対応しています
// map val values = for (value <- Array(1, 2, 3, 4)) yield { value.toString } > Array[java.lang.String] = Array(1, 2, 3, 4) // filter val values = for {value <- Array(1, 2, 3, 4); if (value % 2) == 0} yield { value.toString } > Array[java.lang.String] = Array(2, 4)
- for文は、Javaの拡張for文と同じように使えます
- ブロック/クロージャ
- class
- Javaのclassとほぼ同じ意味として使えます
class Hello { def greeting(msg: String): String = { msg + ", world!" } } class Person { var _name = "" def name: String = _name } - クラス定義とコンストラクタを同時に書けます
class Person(_name: String) { def name: String = _name } - コンストラクタの派生を書くことができます
class Person(_name: String) { def this() = { this("") } } - クラスなどを継承できます
class Foo(foo: String) { } class Boo(foo: String, boo: Integer) extends Foo(foo) { }
- Javaのclassとほぼ同じ意味として使えます
- trait
- object
- case class
- パターンマッチ
- apply
- unapply
- implicit
- 演算子を定義したい
- 単項演算子を定義したい
- 単項の前置演算子としてユーザが定義できるのは、+,-,!,~の4種類です。
class P { def unary_+ :Int = 1 // unary_`operator_name`の形で定義 } println(+new P) // 1のような形でメソッドを定義および使用することができます。 - 単項の後置演算子はScalaでは通常のメソッドと同じように定義します。
class P { def + :Int = 1 } println(new P+) // 1
- 単項の前置演算子としてユーザが定義できるのは、+,-,!,~の4種類です。
def
- setterを定義したい
- getterを定義したい
- 可変長引数を定義したい
- 可変長引数を取るメソッドは以下のようにして定義することができます。最後の引数
の型名の後に*を付けることで、その引数が可変長引数になります。メソッド内部
での可変長引数の扱いは配列と似ていますが微妙に違うので、配列を受け取るメソッド
などに可変長引数を渡したい場合、toArrayメソッドを使用しましょう。
def printAll(xs :Int*) { for(x <- xs) print(x) println() } ... printAll(1, 2, 3) // => 123
- 可変長引数を取るメソッドは以下のようにして定義することができます。最後の引数
の型名の後に*を付けることで、その引数が可変長引数になります。メソッド内部
での可変長引数の扱いは配列と似ていますが微妙に違うので、配列を受け取るメソッド
などに可変長引数を渡したい場合、toArrayメソッドを使用しましょう。
- 可変長引数を取るメソッドに配列などのオブジェクトを展開した要素を渡したい
- 可変長引数を取るメソッドの実引数の後ろに:_*を付けることで可能です。
def printAll(xs :Int*) { for(x <- xs) print(x) println() } ... printAll(Array(1, 2, 3):_*) // => 123
- 可変長引数を取るメソッドの実引数の後ろに:_*を付けることで可能です。
- 「可変長引数を引数に取る関数」の型を記述したい
- val f :Int* => Unit = ...だと構文エラーになります。 val f :(Int*) => Unit = ...のように、可変長引数の型を丸括弧でくくってください。
- 注意:可変長引数を持つ関数のオーバロードには注意が必要
- 可変長引数は、内部的にscala.Seqに変換される。よって、例えば以下のように引数の型が違う様に見えても、内部的には同じtest(scala.Seq)になってしまうため、コンパイル出来ない。
def test(i:Int* ) = "hoge" def test(s:String*) = "piyo"
- 可変長引数は、内部的にscala.Seqに変換される。よって、例えば以下のように引数の型が違う様に見えても、内部的には同じtest(scala.Seq)になってしまうため、コンパイル出来ない。
FAQ(Q&A)
Javaからの移行
- Scalaのfor文はJavaのfor文と違うようですが
- 確かに意味はかなり違いますが,ほぼ同じ事ができます
Java: for(int i = 0; i < 10; i++) { ... } Scala: for(i <- 0 until 10) { ... } Java: for(int i = 0; i <= 10; i++) { ... } Scala: for(i <- 0 to 10) { ... } Java: for(String str : new String[] {"aaa", "bbb", "ccc"}) { ... } Scala: for(str <- Array("aaa", "bbb", "ccc")) { ... }
- 確かに意味はかなり違いますが,ほぼ同じ事ができます
- Scalaのwhile文の中にロジックを書きたい
- Scalaのwhile文はループの評価式しか書けませんのでブロックを使って書きます
Java: int len; while((len = in.read(b)) > 0} { ... } Scala: val len: Int = 0 while({len = in.read(b); len > 0}) { ... }
- Scalaのwhile文はループの評価式しか書けませんのでブロックを使って書きます
- Javaのコレクションを使いたい
- scala.collection.jcl._を使いましょう.Scalaによって機能が拡張されますしGenericsも扱う事ができます
- メソッドをsynchronizedしたい
Java: synchronized void foo() { ... } Scala: def foo() = synchronized { ... } - オブジェクトをsynchornizedしたい
Java: synchornized(foo) { ... } Scala: foo.synchronized { ... } - Javaのequals相当のことをするには?
- Anyクラスのequalsまたは==メソッドを使いましょう。逆にJavaの==相当のことをしたいときは、 AnyRefクラスのeqメソッドを使います。
困った
- パッケージ名に「scala」という名前があると,importできません
- Scalaでは相対的にimportする事ができますが,パッケージ名に「scala」という名前があるとScala本来のパッケージをimportできなくなります.importするときに_root_.を先頭に
付加することで回避できますが、パッケージ名に「scala」という名前を含めない方が無難
でしょう。
import _root_.scala.collection.mutable._
- Scalaでは相対的にimportする事ができますが,パッケージ名に「scala」という名前があるとScala本来のパッケージをimportできなくなります.importするときに_root_.を先頭に
付加することで回避できますが、パッケージ名に「scala」という名前を含めない方が無難
でしょう。
- 予約語と同じ名前のメソッド(ex. Thread.yieldなど)を呼び出しできない
- Thread.yieldの場合は,yieldが予約語で登録されているため,そのままでは呼び出しできません.この場合は,`名前`と書きます
Thread.`yield`()
- Thread.yieldの場合は,yieldが予約語で登録されているため,そのままでは呼び出しできません.この場合は,`名前`と書きます
- i1 & i2 != 0がコンパイルエラーになる
- Javaと演算子の優先順位が違っているためです。括弧を使って(i1 & i2) != 0 とすることでコンパイルが通るようになります。
ソース(src)の説明
リンク
- 公式
- ドキュメント
- ライブラリ
- Scala Actors:Actor関連
- ScalaTest: Scalaテストフレームワーク
- Specs: BDDなテストフレームワーク
- Lift: Webアプリケーションフレームワーク
- 情報源
- Scalaコミュニティ(mixi)
- Scala-ja:日本のScalalian(仮)の寄り合い所w
- LingerBBS
- reddit(Scala)
- 紹介記事
- ブログ
- その他、サンプルコードなど
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)