サイトロゴ

Enjoy Creating
Web & Mobile Apps

MENU BOX
WEB
MOBILE
OPEN

ホーム

 > 

 > 

【静的型付けって?】KotlinとJavaScriptの比較から学ぶ静的型付けの特徴

【静的型付けって?】KotlinとJavaScriptの比較から学ぶ静的型付けの特徴

この記事にはプロモーションが含まれています。

プログラミング言語には色々種類がありますが、それらを分類する方法の一つに、『静的型付け言語 or 動的型付け言語』という分け方があります。

そして、これは筆者の勝手な想像ではあるのですが、独学でプログラミングを学ぶ人の多くが、最初は『動的型付け言語』を選ぶのではないかと思います。

具体的には、JavaScriptPythonか…といったところでしょうか。

これらの言語は、細かい記述ルールに縛られずに『とりあえず』といった感じでもコードを書ける上に、書いたコードを実行してみるのも簡単なので初心者でも学びやすく、書籍やブログ記事の情報も豊富です。

さらに、それらの言語を扱う仕事(需要)も多いとなれば、初心者が最初に学ぶ言語としては最適なのは間違いないでしょう。

なので、プログラミングを学んだことがあるという人でも、意外と『動的型付け言語の経験しかなくて、正直、静的型付けってよく分からない』…といった人は多いのではないでしょうか?

筆者もかつてはその一人で、JavaScriptだけは分かるけれども、TypeScriptやその他の静的型付け言語のことはよく分からないでいました。

静的型付けのメリットもあまり理解できておらず、ただただ面倒くさそう…というイメージを持っていたほどです。笑

ですが、KotlinやSwiftなど、静的型付け言語を扱うようになってからは、静的型付けのメリットや使いやすさを実感するようになりました。

筆者のように、JavaScriptからKotlin、Swiftに進むパターンは稀かと思いますが、今後、JavaScriptだけでなくTypeScriptが必要となるパターンは非常に多くなるでしょう。

なので、ITエンジニアとしてスキルを高めていくためには、動的型付け・静的型付けの両方をしっかり理解することが大切かなと思います。

ということで今回は、これまで動的型付け言語しか学んだことがないという人を対象に、静的型付けの基本について、動的型付け言語との違いを示しながら解説していきます!

なお、動的型付けのサンプルはJavaScript、静的型付けのサンプルはKotlinを使って解説を進めていきますが、プログラミングの基本が分かっていれば、この記事の内容は理解できるかと思います。

この記事を読むことで分かること
  • ・プログラミングにおけるデータ型の基本
  • ・静的型付けと動的型付けの違いと特徴
  • ・静的型付け言語(Kotlin)における変数の宣言
  • ・静的型付け言語(Kotlin)における関数の定義

– 目次 –

データ型のおさらい

まずは、データには型(type)があるということを、軽く復習しておきましょう。

なお、ここで取り上げるのは基本的な型であるプリミティブ型です。(オブジェクト型については触れません)

さらに、特殊な型として扱われることが多いnullについても、ここでは触れません。

null許容とかnull安全(Null Safety)については、静的型付けとは少し話がズレますし、別の分野として捉えた方が理解しやすいかと思います。

上記を踏まえた上で、プログラミング言語にはどのようなデータの型があるのか、使用頻度が高いものを確認してみましょう。

プログラミング言語によって違いはありますが、概ね、プログラミング言語には予め次のようなデータの型が用意されています。

文字列(String)
文字(テキスト)。大抵、"(ダブルクォーテーション)で囲む必要がある
整数(Int)
小数点を含まない数値
浮動小数(Double)
小数点を含む数値
真偽値(Boolean)
trueまたはfalseで表す

データ型が異なれば、同じ値(に見えるもの)でも、違うものとして扱われます。

例えば整数型の1と、浮動小数型の1.0は、異なるデータということになります。(JavaScriptではどちらもひっくるめてNumber型となっています)

同様に、文字列型の"1"と整数型の1、文字列型の"true"と、真偽値のtrueなども、別のものとして扱われるのが基本です。

数値の1と文字列の1、真偽値のtrueと文字列のtrueは同値ではない

しかし、正直なところ、JavaScriptではこれらの違いについてそこまで気をつけていなくても、プログラムコードは書けてしまいます。

JavaScriptでは、例え同一の変数であったとしても、どのようなデータ型でも代入できる仕組み(=動的型付け)になっているからです。

例えば、変数numberを宣言して、最初は整数型(JavaScriptにおいてはnumber:数値型)の数値を代入したとします。

JavaScript

let number = 5; // 数値(number)の5が代入される

console.log(typeof(number)); // number

ここまでは別に何の問題もありませんね。

では次に、同じ変数に文字列型のデータ("5")を代入してみましょう。

この時、JavaScriptでは特にエラーなど起こさず、データ型が異なる値をすんなり代入できてしまいます。

JavaScript

number = "5"; // 文字列(string)の"5"が代入される

console.log(typeof(number)); // string

【number】…なんて、いかにも数値型のデータが入っていそうな変数に、文字列型のデータが入ってしまいました。

この方が自由にコードを書けて便利だと感じる方もいるかもしれません。

実際、静的型付けの方が絶対に良いとか、静的型付け > 動的型付け という不等式が成り立つ優劣関係であるとか、そういうわけではなく、動的型付けだからこそのメリットもあります。

しかし、一般的には、このような仕様は混乱やバグの元となることが多いです。

numberと名付けられた変数があったら、多くの人は数値型のデータが格納されているはずだと予想するでしょう。

numberが数値型であることを利用して、他の数値と合算したり…といった機能を追加しようと考えるかもしれません。

ですが、実態は文字列型だった…となれば、当然ですが(そのままでは)他の数値と足したり引いたりといった四則演算を行うことはできないので、開発者は紛らわしい変数に苛立ちを覚えることは間違いないでしょう。笑

では、こんな時、変数numberに代入されているデータが数値型であることが保証されていればどうでしょうか?

それなら安心してnumberを扱うことができそうですよね。

これを可能とする仕組みが、今回の記事のテーマである『静的型付け』です。

次の章では、静的型付け言語における変数の宣言と値の代入例を見ていきましょう。

    POINT!
  1. ・データ型には文字列、整数、真偽値などの型があり、それぞれ別のデータとして扱われる!
  2. ・JavaScriptでは、同じ変数に異なるデータ型の値を代入できてしまう!
  3. ・この方が便利な場合もあるが、一般的には混乱やバグを招いてしまいやすい!

静的型付け言語における変数宣言

この章では、静的型付け言語であるKotlinで変数を宣言し、その変数に値を代入する例を紹介しながら、静的型付けの特徴を掴んでいきたいと思います。

ちなみに、Kotlinとは主にAndroidアプリ開発に使われますが、Javaと互換性があるため、幅広い分野で活躍できるのが魅力的なプログラミング言語です。(筆者的に、書いていて一番楽しいプログラミング言語だと思います)

Kotlinのような静的型付け言語では、変数を宣言する際、どのようなデータ型を入れる変数であるのかを明記します。(後で説明しますが、省略できる場合もあります)

Kotlin

var number: Int = 5
println(number::class.simpleName)  // Int

コードをよく見てみると、number変数の横に、: Int…という表記がありますね。

これがデータの型を宣言している部分であり、numberはInt型のデータが代入されていることが保証されます。

言い換えれば、numberには整数(Int)型以外のデータ型を入れることができません。

実際、文字列型のデータを代入しようとしてもコンパイルエラーになります。(エラーメッセージが表示され、コードを実行することができません)

Kotlin

var number: Int = 5
number = "5" // これはエラーになります

ただ、データの型が保証されるのはありがたいとしても、変数を宣言する際にいちいちデータの型を明記するのは面倒くさいですよね。

そこで、Kotlinをはじめとした静的型付け言語では『型推論』という仕組みが用意されていることが多く、わざわざ型を明記せずとも自動で型を指定してくれます。

例えば、変数xに1が代入されるのであれば、必然的にデータ型は整数型(Int)であることが推論されるので、xのデータ型はIntとなります。

具体的には次のように変数を宣言することが可能です。

Kotlin

var x = 1 // データ型は自動的にIntになる

このように型推論を利用する場合も、データ型の宣言を省略できるというだけで、変数のデータ型が決まっていないわけではありません。

なので、Int型と推論されたxに文字列型のデータを代入しようとすると、やはりエラーになります。

Kotlin

var x = 5 // 型推論によってInt型となる
x = "5" // なので、これはエラーになります

さらに、動的型付け言語のJavaScriptでは、とりあえず変数を宣言しておくだけ(値を代入しない)にしておき、その状態のまま変数を参照するということも可能ですが、静的型付け言語のKotlinでは、変数とデータ型を宣言しただけでは、その変数に指定されたデータ型の値が入っているとは言えないので、エラーになります。

JavaScript

let unknown; 
console.log(typeof(unknown)); // undefinedが出力され、エラーになるわけではない

Kotlin

var integer: Int
print(integer) // エラー:Variable 'integer' must be initialized

このように、静的型付け言語では厳密なデータ型のチェックが行われるので、指定したデータ型ではないデータ型の値が代入されてしまったり、指定したデータ型の値の代入が忘れられたまま処理されてしまったり…ということが起こり得ません。

この特徴は、特に複数人で大規模なプロジェクトを開発する際に有利に働くと言えます。

一方、個人でちょっとしたものを開発・テストする程度であれば、静的型付けによる恩恵はそこまで感じられないかもしれません。

ですが、静的型付けのメリットは『指定したデータ型の値が入っていることが保証されること』だけではありません。

次の章では、個人開発においても『静的型付けって便利だな』と思わせれてくれる特徴をご紹介します!

    POINT!
  1. ・静的型付け言語では、変数に代入可能なデータの型が宣言時に決定される!
  2. ・型を明示的に宣言しなくても、型推論によってデータの型が決まる!
  3. ・型だけ宣言して変数を参照した場合も、エラーになる!

静的型付け言語における関数定義

個人開発でも、他の人が書いたコードを参考にしたり、ライブラリを利用したりすることはよくありますよね。

ですが、他人が書いたコードを読み解いたり、他人が作ったライブラリの仕様を理解したりするのは、一筋縄ではいきません。

言い換えれば、個人開発であっても『他人が書いたコードを見て理解できる』ことは必須であり、避けては通れないということです。

であれば、他人の書いたコードが少しでも理解しやすいものであるに越したことはありませんよね?

そこで、活躍するのが『静的型付け言語における関数のパラメータ・戻り値の型チェック』です。

動的型付け言語であるJavaScriptの場合、何か便利な処理をしてくれる関数があったとしても、その関数には何を引数として渡せば良いのか?とか、関数の処理によって最終的に返される値(戻り値)は何か?ということを知るには、関数の処理の中身を細かく確認しなければなりませんよね。

例えば、秒数(整数)を分に変換して、『○○秒は××分です』というメッセージ(文字列)を返してくれる関数があったとしましょう。

この時、この関数に渡す引数は整数、戻り値は文字列ということになります。

文章で書くと当たり前じゃないかと思うかもしれませんが、関数で表記すると、意外とややこしいものです。

まずはJavaScriptでこの関数を表してみましょう。

JavaScript

function secondsToMinutes(seconds) {
    return `${seconds}秒は${seconds / 60}分です`;
}

console.log(secondsToMinutes(600)); // 600秒は10分です

この関数の処理を理解しようと思ったら、returnで返される値や処理の内容を確認・理解した上で、secondsにはどんな値を引数として渡せば良いのかを頭の中で整理する必要があります。

これぐらい処理の内容が簡単な関数でも、パッと見た瞬間に正確に把握できる人は少ないのではないでしょうか。

さらに、この関数の場合、関数の処理を勘違いしてしまって文字列型のデータを渡したとしてもエラーが起こるわけではないので、勘違いに気付けない可能性もなくはありません。

JavaScript

function secondsToMinutes(seconds) {
    return `${seconds}秒は${seconds / 60}分です`;
}

console.log(secondsToMinutes("600秒")); // 600秒秒はNaN分です(エラーにはならない)

パラメータに整数以外の値が渡された時にエラーや警告のメッセージを表示させたければ、関数内にメインの処理とは直接関係ない例外処理などを書かなくてはならなくなり、コードの記述量が増えてしまいます。

一方、静的型付け言語のKotlinであれば、関数のパラメータや戻り値のデータ型を指定する必要があるので、どんな値を引数として渡せば良いのか、そしてどんな値が返されるのかが一目で分かります。

Kotlin

fun secondsToMinutes(seconds: Int): String {
    return "${seconds}秒は${seconds / 60}分です"
}

println(secondsToMinutes(600)) // 600秒は10分です

パラメータのsecondsには、: Int の表記により整数型を渡せば良いということがわかりますし、その後の :String の表記により、文字列型のデータが戻り値として返されることが明確になっていますね。

静的型付けにより、関数の中身を全く見ずとも、『引数として渡した整数をもとに、何らかの処理を行って文字列にしてくれる関数である』ということが分かるようになっています。

当然、指定された型以外のデータ型を引数にして関数を実行しようとしてもエラーが起こるようになっているので、安心して使うことができます。

Kotlin

fun secondsToMinutes(seconds: Int): String {
    return "${seconds}秒は${seconds / 60}分です"
}

println(secondsToMinutes("600")) // 文字列型を渡しているのでエラーになります
// Type mismatch: inferred type is String but Int was expected

この違いにより、他人が書いたコードを読み解いて利用するという点においては、静的型付け言語の方に優位性があると言えます。

前述したように、動的型付け言語より静的型付け言語の方が全てにおいて良い(完全上位互換)だと言いたいわけではないのですが、モダンなプログラミング言語は静的型付けの機能を備えていることが多く、時代の流れとしては静的型付けの方に傾いているのではないかと感じます。

だからこそ、本来はJavaScriptで全て事足りるにも関わらず、JavaScriptではなくTypeScriptが採用されたり…といった傾向が強まっているのではないでしょうか。

というわけで、ある程度JavaScriptに慣れて余裕が出てきたら、TypeScriptやその他の静的型付け言語の基本を学んでみるのもオススメですよ!きっと、世界が広がるはずです。

    POINT!
  1. ・静的型付けでは、関数のパラメータや戻り値にもデータの型を明示する必要がある!
  2. ・なので、関数に渡す引数や戻り値のデータ型を一目で確認できる!
  3. ・静的>動的というわけではないが、静的型付けの特徴にも慣れておくと今後役に立つかも!

« »

カテゴリーリンク

著者について- author profile -

ROYDOプロフィール写真
Michihiro

モバイルアプリ(iOS・Android)ディベロッパー&デザイナー

これまでに、可読性の高いカラーパターンを自動で生成するアプリや、『第3火曜日』といった形式で通知をスケジュールできるアプリなどを制作。

サブでWebデザイン・フロントエンドエンジニアとしても活動しています。

📝ツール・言語:JavaScript/React Native/Kotlin/Android Studio/Swift/SwiftUI

🎓資格:基本情報技術者/ウェブデザイン技能検定3級

Twitterアイコン Instagramアイコン