この記事はscala advent calendarのDay2です(`・ω・´)
scalaの言語仕様書の4ページあたりに記載されてる、予約語についてひと通りまとめてみます。ちょっと時間なくて説明適当なところとかあるのはあとで直します、すいません(´Д`)
ちょっとだけ追記した
仕様書↓

abstract
抽象クラス表すのに使用。ちなみに、メソッドやフィールドがabstractでも、scalaの場合は、abstractはつけません(つけると以下のようにエラーになる)
scala> abstract class A{ | abstract def hoge | } <console>:6: error: `abstract' modifier can be used only for classes; it should be omitted for abstract members abstract def hoge
case
たぶん使うとこ4種類ある。前のこのエントリ参照wと思ったら、例外のcatchの後にもでてくるじゃん!ってことで5種類ですかね?
catch
例外受け取る。ただし、catchの部分の書き方がjavaと異なる。以下同じ処理のjavaとscalaで書いたtry{ // 何らかの例外が投げられる可能性のある処理 }catch(IOException e){ println("IOException発生したお") }catch(Exception e){ println("Exception発生したお") }
try{ // 何らかの例外が投げられる可能性のある処理 }catch{ case _ : IOException => println("IOException発生したお") case _ : Exception => println("Exception発生したお") }
class
classの定義。まぁjavaと同じdef
関数の定義。ローカル関数*1の定義にもdo
do whileのdo。javaと同じelse
if else で使う。if 〜 else 〜 の全体そのものが式で、値返すところがjavaと異なるextends
クラスを継承するとき。Javaでは、型パラメータの境界を示す場合にも使用するが、scalaでは <: を使用するfalse
Boolean型のリテラル。Javaのfalseと全く同じfinal
classが継承できないことをあらわす。Javaでは変数にfinalを付けると再代入不可能な変数を意味するが、scalaの場合はvalを使用するjava | scala | |
---|---|---|
再代入可能な変数(mutable) | int a = 1 | var a = 1 |
再代入不可能な変数(immutable) | final int a = 1 | val a = 1 |
あと、メソッドがoverrideできないこと示す。これもjavaと同じ
finally
javaと同じ。ちなみに、finallyの中のは値かえさない。for
javaと同じでループの処理・・・ではない!*2foreach、map、filter、(2.8以降はwithFilterも) の(組合せの)シンタックスシュガー。
forSome
えーと、普通は省略できるから殆ど使わないんだっけかなぁ・・・。型書くところで使うんだけど。すいません、あとで調べます(´Д`)まぁ初心者のうちは知らなくても困りません。
if
if式それ以外にも、match式のcaseの部分や、for式の、パターンガードでもつかう
implicit
大きく分けて2種類*3。暗黙変換(implicit conversion)と暗黙引数(implicit parameter)。追記
2.8から無名関数のリテラルを書く際の引数の場所に書く文法があるらしい*4
import
基本はjavaと同じ機能。がそのほかにも色々機能追加されてる。- 一行で複数のclassインポートできる便利な書き方
- 別名(alias)つける
- fileの先頭以外でもimportできる
- package名をimportできる
- ある特定のものを除いて、それ以外importとか
lazy
変数の遅延評価。初めてアクセスしたときに評価される。2回目以降は、1度目に評価した値を返す。match
javaのswitchをものすごく汎用的にした感じ。詳しく書ききれないので、機能の詳細はとりあえず省略wnew
javaと同じ。インスタンス生成null
Nullクラスの唯一のリテラル。javaのnullと同じobject
シングルトンを定義する。先頭が小文字というのに注意。scalaの場合でも、先頭大文字で単にObjectと書けば、java.lang.Objectを表すことになる。override
overrideした場合に、必ずつけないといけない。C#のoverrideキーワードに似てる。ちなみに、scalaではvalやvarもoverrideできる。*6
package
packageの定義。Javaと同じようにも使えるが、異なる構文もある。たとえばListの先頭は以下のようになってますpackage scala.collection package immutable
これは以下のように1行で書いたものと意味が異なります!
package scala.collection.immutable
あとこんなふうに中括弧つかって同一ファイル内に複数のpackage書けたり
package a{ //ここの名前空間は a package b{ //ここの名前空間は a.b } }
それとpackage objectの定義にも使いますね
private
普通に書くとjavaと同じように使えるが、異なる構文もある。普通に書くとclass内でのみアクセス可能だが、以下のように
private[this]
と書くと、そのインスタンス内でのみアクセス可になる。ほかにも上記のthisの部分にpackage名入れたりとかして、javaより柔軟にアクセス制御できる
protected
普通に書くとjavaと同じように使えるが、privateの場合と同じく、そのあとに、公開する範囲を指定できるreturn
関数から戻り値返す。scalaの場合省略できるので、普通書かない。また、returnを書くと、関数の戻り値の型を明示しないといけないという決まりがある。sealed
classにつける。それをつけたものは、同一ファイル内のclassからしか継承できなくなる。Listがsealedクラスで、:: と、 Nil が同じファイルに定義されていたりとか有名(?)ですよね
super
superクラスのメソッド呼ぶときとか・・・。他になにかあったっけ?記憶が曖昧(´・ω・`)javaと違って、型引数の境界あらわすのには使いません!
this
プライマリ以外のコンストラクタ。javaと異なる*7ちなみに、scalaのコンストラクタは、javaと違って色々制限が厳しくなってるので、慣れないと最初結構戸惑うとおもいます。
scalaでは、プライマリコンストラクタ以外のコンストラクタは、super classのコンストラクタを呼べなかったりとか。
あとは、classのインスタンスメソッド内のコンテキストで、そのインスタンス自身を示す場合に使用。(これはjavaと同じ)
throw
例外なげる。javaと同じtrait
一言で言うとRubyのModule。実装を持ったinterfaceって言えばいいんでしょうか?ここもちょっと説明しきれないので、とりあえずこんな感じで。
try
javaと同じ。けど、try 〜 catch 自体が式であり、値を返すtrue
Boolean型のリテラル。javaのtrueと同じtype
javaにはないキーワード。型自体の別名(alias)を定義したり。また、抽象型というものを定義したり。*8
val
再代入不可能(immutable)な変数を定義するvar
再代入可能(mutable)な変数を定義するwhile
javaとまったく同じwith
traitをMixinするとき。classやobject定義の場所以外でも使えるyield
for式が値を返す場合に使う@
アノテーションをつけるとき。ちなみにjavaの場合、アノテーションの定義にも@を使う*9が、scalaの場合は単に、StaticAnnotationクラスを継承したクラスを定義する
そして、match式での変数束縛パターンというあまり知られていないマニアックな機能もある
#
え〜〜〜となんだっけw追記しますた(・ω・)
classの内部classの型名を書く場所で使う。以下REPLで試したものをそのまま貼りつけ(コメントは追加したけど)
#の使い方と、classの内部クラスと、objectの内部classの違いの説明*10
scala> class A{ //Aというclassと、その中に、Bという内部class定義 class B{ } } defined class A scala> val a = new A() //Aのインスタンス作成 a: A = A@52744 scala> val b:A#B = new a.B() // Aのインスタンスをつかって、Aの内部classであるBのインスタンス作成 b: A#B = A$B@1557a77 scala> val c:A.B = new a.B() // この書き方は間違い <console>:7: error: not found: value A val c:A.B = new a.B() ^ scala> object A{ //Aのobjectと、その内部class定義 | class C{ | } | } defined module A scala> val c:A.C = new A.C() // objectの内部クラスの場合はこういう書き方 c: A.C = A$C@1d869b2 scala> val c:A#C = new A.C() // 逆に、#をつけて書くとエラー <console>:7: error: type C is not a member of A val c:A#C = new A.C() scala> new A.B() // Aのインスタンスが存在しないとBのインスタンスは作成できない <console>:7: error: type B is not a member of object A new A.B() ^ scala> new A#B() // 上記と同じく、こういう書き方してもインスタンスは作成できない <console>:7: error: A is not a legal prefix for a constructor new A#B()
他に#出てくる場所ってあったっけ?(´・ω・`)
:<
上限境界%>
可視境界。:>
下限境界。<-
for式でつかう=>
関数リテラル定義するときに、引数 => 関数本体の式
という形で使用
=
変数に代入するとき。関数定義するとき。*11
:
変数名:型名関数の引数:型名
def ( 引数のりすと ):関数自体の型名
とか*12
_
関数リテラルのプレースフォルダー
パターンマッチの際に、使用しない(抽出してもその後使わない)変数を明示するとき
*1:関数の中の関数
*2:for(i <- 1 to 10) っていう感じで見た目はループっぽく使えるけど、実は関数の呼び出し
*3:変換を分けると3種類になる気もするが。単に変換する場合と、暗黙的に変換した後、さらにその変換後のclassのメソッドを呼び出す場合があるから
*4: けど自分も全然意味とか使い方分かってない。だれか教えて(´・ω・`)
*5:たとえば、GAEとかってスピンアップの時間が重要だから、classのフィールドなんかでうまく使えば便利かもね。と思いついてみたり
*6:valやvar自体、普通に定義した場合、自動でアクセサメソッドができるから
*7:javaの場合コンスタントラクタ書くときは、class名を書く
*8:そういえばthis.typeとかって使い方もあるなぁ・・・
*9: @interface っていう感じで
*10:概念自体は、Javaの場合のstaticな内部classと、staticでない内部classと同じですね
*11:どうでもいいけど、これが予約語なら、カッコとかも予約語じゃないの?予約語の定義ってなに?
*12: 何だこの説明orz