ラベル Scala の投稿を表示しています。 すべての投稿を表示
ラベル Scala の投稿を表示しています。 すべての投稿を表示

2013年3月23日土曜日

Scalaのお勉強 第2回:「Scalaプログラミングの次の一歩」(前編)


はじめに




前回のScalaの記事から,1ヶ月半ほど経ってしまいました.

今回はコップ本の第3章「Scalaプログラミングの次の一歩」を読んだので,記事を書きます.

この第3章,内容をブログにまとめようとすると,結構な量になってきたので,記事を2つに分けようと思います.









パラメータ化




パラメータ化 = "生成するインスタンスの「構成を設定する」こと"

Javaで言えば,オブジェクトを作る時に,コンストラクタへ引数を渡すのと同じ(?)




val greetStrings = new Array[String](4)


上の例では, Array[String] 型のオブジェクトに (4) とすることで,長さ4の配列であると構成を設定している.

greetStrings の型が Array[String] であるのもポイント.









型コンストラクタ




Array は型コンストラクタと呼ばれるもの.

型コンストラクタに型変数を与えることによって,初めて型として成り立つ.

関数にいくつかの引数を与えて,値になるようなイメージで型を作る仕組み.

Haskellにもあった概念だと思う.









valで宣言した配列の書き換え







val greetStrings = new Array[String](4)    

greetStrings(0) = "Hello"
greetStrings(1) = ", "
greetStrings(2) = "world"
greetStrings(3) = "!\n"

for(i <- 0 to 2)
print(greetStrings(i))



greetStringsval で宣言している.

val で宣言したものは,再代入できない.

ところが,上記のコード例のように, greetStrings の要素には代入できる.

なぜなら, greetStrings の要素への代入しても, greetStrings には再代入していないためである.

もちろん, greetStrings = greetStirngs2 のような,再代入はできない.

これをCのポインタでいうと,ポインタ変数に格納しているアドレスは書き換えられないけど,ポインタが指す先にあるデータ領域は書き換えられる,ということである.

Cのコードで書くとこうなる.







char *const str1 = (char*)malloc(sizeof(char)*4);
char *str2 = (char*)malloc(sizeof(char)*4);

strcpy(str1, "ABC");
strcpy(str2, "DEF");

str1[1] = 'G'; //OK
str1 = str2; //Error








さまざまな糖衣構文




先ほど示したScalaのコード例の中には,様々な糖衣構文が存在する.


  • 0 to 2(0).to(2) の糖衣構文.


  • greetStrings(i)greetString.apply(i) の糖衣構文.


  • greetStrings(1) = "Hello" greetStrings.update(1, "Hello") の糖衣構文.


  • 1 + 2(1).+(2) の糖衣構文.




このように,さまざまなものが,メソッド呼び出しに変換される糖衣構文(syntax suger)である.






おわりに




今回はコップ本の第3章「Scalaプログラミングの次の一歩」を読んだまとめ(前編)を書きました.

後編はいつになることか…

あんまりがっつり書くと時間がかかるので,次回からもう少しはしょりながら書こうかと思ってます.




--
My Emacs Files At GitHub

2013年2月9日土曜日

Scalaのお勉強


はじめに




来年度から,Scalaを使うことになるそうなので,Scalaをちまちま勉強しています.

教材はこれ(通称コップ本).


この本の一つの章が終わるたびに記事を書こうと思います.

ちなみにこの本の章構成はこんな感じです.

コップ本の目次


基本的に,自分が気になったところだけ抜粋して書くつもりです.

僕は,C,Javaあたりの言語に親しみがある人間です.

あと,Haskellを勉強する機会もありました(あんまりわかってない疑惑あり).

ですので,これらの言語との違いや似ている部分を主に書くと思います.

あと,箇条書きが多いです.

今回は2章「Scalaプログラミングの第一歩」を勉強したまとめです.


saclaインタプリタの使い方

$ scala
     Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_07).
Type in expressions to have them evaluated.
Type :help for more information.
scala> 1 + 2
res0: Int = 3

scala> res0 * 3
res1: Int = 9

scala> :q

  • 先に計算した結果は自動で res0 などに格納される
  • 計算結果の Int などは結果のデータ型
    これは,Scalaインタプリタが型推論し導いている

変数,定数の使い方

scala> val hoge = 0
hoge: Int = 0

scala> var piyo = "piyo"
piyo: java.lang.String = piyo

scala> piyo = "piyopiyo"
piyo: java.lang.String = piyopiyo

scala> hoge = 1
<console>:8: error: reassignment to val
    hoge = 1
         ^

  • val <定数名> = <値>定数 を定義する.

    (val はvalueの意)
  • var <変数名> = <値>変数 を定義する.

    (var はvariableの意)

  • 定数と変数はともに,初期値なしで宣言できない.
  • 定数には再代入できない.
  • 宣言時にデータの型を明示する場合は
    val <定数名>: <データ型名> = <値>
    と定義する.
  • データ型名を変数の後ろに書くのは,型推論によってデータ型名を省略できるようにするため.
    (データ型名を前に置く文法にすると,省略したときに,宣言か否かの判別ができない.)

関数の使い方

scala> def add(x: Int, y: Int): Int = {
  |   x + y
  | }
add: (x: Int, y: Int)Int

scala> add(1, 2)
res0: Int = 3

scala> def hello() = {
  |   println("hello")
  | }
hello: ()Unit

scala> hello()
hello

scala>
  • 関数の宣言は以下のフォーマットである.

    def <関数名>(<仮引数名1>: <仮引数1のデータ型名>, ...): <関数の戻り値のデータ型名> = {関数本体}
  • '{'の前の'='の書き忘れに注意が必要.
  • 戻り値は関数本体の最後の式が返す値となる.
  • 関数の戻り値は型推論される.
  • 仮引数は 型推論されない.
  • Cなどの void 型に相当するものはが Unit である.

配列の参照

  • 配列へのアクセスは

    array(0)

    のように書く.

    array[0]

    のようには書かない.

コマンドライン引数

  • コマンドライン引数を格納するのは args という名の文字列の配列である.
  • args(0) はプログラム名ではない.

    cf. C言語の argv の最初の要素はプログラム名である.

foreach


args.foreach(arg=> println(arg))
args.foreach((arg: String) => println(arg)) //上と同じ処理を行う
args.foreach(println) //部分適用
  • (arg: String) => println(arg) の部分を関数リテラルという
  • 引数の型(上の例では arg の型)は省略できる
  • 引数の型を明示する場合は,引数を示す部分を括弧で括る.
  • foreach は引数に関数を取る,ということだと思う.
    関数型言語では,関数も値と同じように扱う.

for式

for(arg <- args){/*argを用いた処理*/}
  • for(<定数名> <- <配列名>){処理} でループが回るたびに配列の中身を定数に一つずつ入れ,処理する.

その他

  • scalaの推奨インデントはスペース2つである.
  • scalaでは ++ii++ は使えない

おわりに

というわけで,Scalaの最初の一歩を踏み出した感じです.

さて,いつまで続くでしょうか…



--
My Emacs Files At GitHub

2012年9月23日日曜日

sbtの導入


いろいろあってScala+JavaFXでテトリスを作ることになりそう.
なので,まずsbtを導入します.


環境






  • Mac OS 10.7.4(Lion)







sbtのインストール




sbtのインストールは sbt-launch.jar をダウンロードし,これを実行するスクリプトを作成することで完了する.
例として ~/local/bin/sbt/ の下にインストールする手順を以下に示す.


  1. sbt-launch.jar から sbt-launch.jar をダウンロード.これを ~/local/bin/sbt/ の下に置く.


  2. sbt というファイル名でスクリプトファイルを作る.
    スクリプトの中身は以下のようになる.



    java -Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=384M -jar `dirname $0`/sbt-launch.jar "$@"






  3. スクリプトファイル sbt に実行権限を与える.
    $ chmod +x ~/local/bin/sbt/sbt


  4. PATHを通す.
    ~/.bash_profile に以下の行を追加



    export PATH=/Users/<ユーザー名>/local/bin/sbt/:$PATH







これでインストールは完了





とりあえずHello World




とりあえず,Hello Worldを出力するだけのプログラムを実行してみる.
プログラムは ~/hello 以下に作成する.
手順を以下に示す.



$ cd ~
$ mkdir hello
$ echo 'object Hi { def main(args: Array[String]) = println("Hello World!") }' > hw.scala
$ sbt
...
> run
...
Hello Wolrd!










おわりに




とりあえずこれでHello Worldができた.
使い方など,もっとsbtのことを知りたい人は参考URLを見てください.
というか,この記事よりも参考URLの方がわかりやすいと思います.





参考URL





--
My Emacs Files At GitHub