ScalaでAndroidアプリを作成する準備

ScalaでAndroidアプリを作成するために準備をする。

HomebrewでScala/sbt/giter8をインストール。

$ brew install scala sbt giter8

giter8でテンプレートからファイルを作成。

$ g8 jberkel/android-app
package [my.android.project]: com.example.myproject
name [My Android Project]: My Project
main_activity [MainActivity]:
scala_version [2.9.2]:
api_level [10]: 14
useProguard [true]:
scalatest_version [1.8]:

みたいな感じで。

さらにIntelliJ IDEAのプロジェクトにする。

project/plugins.sbtに

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.4.0")

を追加。addSbtPluginを複数記述する場合はaddSbtPlugin行間に空白行が必要。

$ sbt
> gen-idea
を実行。

> android:package-debug
> android:install-device

でビルドして実機に転送。

型推論について調べてみた

型推論 – Wikipedia
型推論とは – はてなキーワード

によると、
動的型付言語では実行時に型が決まるので型の宣言は不要だが、静的型付言語ではコードで変数や関数の型を宣言する必要がある。この変数や関数の型の宣言をしなくてもよくなるのが型推論らしい。関数の型シグネチャなどから自動的に型を決定してくれる。
var result
result = x + 1
だとhogeはintだろうと推論してくれる。

メリット

  • 誤った型を用いる事によるバグは回避できる。
  • 記述をアルゴリズムに集中できるのでプログラムの抽象度が上がる

Scalaの関数

Scalaで関数を作成してみます。

def max(x: Int, y: Int): Int = {
    if (x > y) {
        return(x)
    } else {
        return(y)
    }
}

大きい方の数値を返す関数です。
def 関数名(引数: 型[, 引数: 型]): 返値の型 = {}
で定義するということです。

最後に評価したものが返値になるので、 以下のようにreturn(x)という部分はxのみでもいいようです。

def max(x: Int, y: Int): Int = {
    if (x > y) {
        x
    } else {
        y
    }
}

さらに返値であるxやyがIntだと型推論できるときは、以下のように返値の型は省略できるようです。

def max(x: Int, y: Int) = {
    if (x > y) {
        x
    } else {
        y
    }
}

ただし、return(x)とした場合は型推論できない(?)ということで、返値の型の省略ができませんでした。型推論についてよく知らないので、次は型推論について調べてみようと思います。

Scalaスクリプトをshebang行で実行するにはどうすればいいの?

$ scala hoge.scalaではなく、Scalaスクリプトに実行権限をつけて$ hoge.scalaで実行したいんです。で、

#!/usr/bin/env scala
print("abc")

とやってみました。
error: script file does not close its header with !# or ::!#
one error found
と、おこられました。

/opt/bin/scalaの中身ってどうなってるの?というわけでlessしてみたらシェルスクリプトでした。最終的には

exec "${JAVACMD:=java}" $JAVA_OPTS -cp "$TOOL_CLASSPATH" -Dscala.home="$SCALA_HOME" -Denv.classpath="$CLASSPATH" -Denv.emacs="$EMACS"  scala.tools.nsc.MainGenericRunner  "$@"

と実行してました。Mac OS Xでgroovyスクリプトをshebangで実行 – Grな日々(uehajの日記)(広告が懐かしすぎ)が参考になるかと思って、少しいじってみましたが知識少なすぎでまだ出来てません。

Scalaの変数

Scalaには2つの変数があります。

valとvarです。

valは再代入ができない変数です。valueを短縮したものですね。varは再代入ができます。variableなので正確にはこちらが変数でvalは値といった方がいいのでしょうか。

早速試してみます。まずはval。


scala> val la = “val test”
la: java.lang.String = val test

scala> print(la)
val test
scala> la = “another”
:5: error: reassignment to val
la = “another”
^

scala> la = null
:5: error: reassignment to val
la = null
^

はじめにlaに”val test”という文字列を代入しました。printしたのちlaに再度”another”という文字列を代入しようとしてもエラーが発生しています。nullの代入も同様です。

今度はvarを使ってみます。


scala> var ra = "var test"
ra: java.lang.String = var test

scala> print(ra)
var test
scala> ra = "another"
ra: java.lang.String = another

scala> print(ra)
another
scala> ra = null
ra: java.lang.String = null

scala> print(ra)
null

varでは再代入できました。

上記ではvarに文字列を代入して、再度文字列を代入しましたが、再代入で数値を入れてみます。

scala> ra = 1
:5: error: type mismatch;
found : Int(1)
required: java.lang.String
ra = 1
^

一度文字列を代入したものには文字列以外は代入できないようです。

でははじめに数値を代入して数値を再代入してみます。

scala> var num = 2
num: Int = 2

scala> num = num * 5
num: Int = 10

ということで、今回はここまでにしときます。

Scalaの複数行にわたる文字列

Scalaでの複数行にわたる文字列は、”””で囲むということです。試してみます。

scala> print("""abcd
     | efgh""")
abcd
       efgh

また、上記の|は環境により自動的に表示されているものですが、ソースコードで

var a = """abcd
               |efgh"""

のようにすると、efghの行頭の|までのスペースは無視されるということです。試してないですが。

ScalaでHello world!

Scalaのインストールが完了したので、早速Hello world!やってみます。
シェルでscalaコマンドを実行すると、scalaの対話式実行環境が起動します。

scala> print("Hello world!")
Hello world!
scala> println("Hello world!")
Hello world!

scala> printf("%s %s", "Hello", "world!")
Hello world!

printfはネットではprintf(“{0}”, “hoge”)のような記述が見られるんですが、試しても{0}と出力されるだけでした。これはバージョンの違いなんでしょうか。使ってるのは2.7.4.finalなんですが。

それから文字列は”hoge”で文字は’h’ですね。はじめ’hoge’してエラーが出ました。最近はPHPやらRubyやらなのですっかり忘れていましたが、Javaはchar型があるんでしたね。Scalaにもcharがあるんですね。

ScalaをMacにインストール

なんだかScalaが素敵に見えてきたので、Scalaに入門してみます。

とりあえずscalaをMacPortsでインストール。

$ sudo port install scala

それからEclipseもダウンロードしました。
Eclipseなんて久しぶりです。アイコンのデザインがいまいちなんですよね・・・scalaとは関係ないけど。

Scala plugin for eclipseはこの更新サイトからインストールできます。