Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Swift
入門編
- トップページ
- Swift入門編 - データ型とは
データ型とは
みなさまどうも。
では続きまして『データ型』についてやっていきましょう。『データ型』は単純に『型』ともよばれますね。
初心者殺しとして有名な項目でございますが、Swiftは『データ型』について非常に厳格です。なので避けて通れない項目になっちゃってます。結構大変かもですが頑張っていきましょう。
まず『データ型』とはなんぞや、ってお話なんですが、『データ型』とはプログラムで使うデータをいくつかの種類に分類したもので、一種のカテゴリー分けみたいな感じで使われています。
これまで数値と文字列についてやりましたが、通常の整数ならば『Int型』、通常の文字列ならば『String型』というのが内部で使用されており、これらが『データ型』に該当しますね。
そしてSwiftでは変数とか定数を定義するときに型を前もってしっかり指定した状態にする必要があったりします。
※『変数』と『定数』については次の記事で解説します。
なんで前もって型の指定をしなくちゃならないかというと、いくつか理由があったりしますがまず第一に「前もってメモリの確保をする」っていう目的を達成するためだったりします。
「よく分からんぜー」って方も多いかと思いますので、ちょいとパソコン君とかスマホ君とかの構造とプログラムの裏側の動作について確認していきましょう。
今、このウェブサイトを見るためにパソコン君やスマホ君とかを使っているかと思いますが、この両デバイスは共に『メモリ』っていう部品を持っており、全てのプログラムはこの『メモリ』に一時的なデータを保存することで処理を実現しています。
さて、その『メモリ』に情報を保存するためにはデータの書き込み場所(アドレス)とデータの内容(0と1で構成されたバイナリ)を指示する必要があります。
昔はそれら全てをひとつひとつ指示してプログラムをしていたのですが、昨今のほぼ全てのプログラム言語になるとその辺の処理は全部裏側で適当にやってくれるようになっています。Swiftも然りですね。
とっても便利で楽ちんになったわけなんですが、ここで少し問題が発生します。
『メモリ』はOSや他のアプリケーションなどでも同時に使用されるため、自分が作ったプログラムで使用するであろう『メモリ』の書き込み場所を前もって確保しなくてはならなくなりました。
新しい処理をしてデータを保存しようと『メモリ』を見に行ったら他のアプリケーションに使われていた、となると大変です。こういう時プログラムはどういう動作になるかというとズバリ、落ちます。
「メモリ不足で落ちたー!」なんて悲鳴を聞いたことあるかと思いますが、それは『メモリ』に書き込みに行ったら他のアプリケーションに場所を取られていたりメモリ容量が足りなかったりで書き込めなかった、というのが原因だったりしますね。
なのでプログラムを実行できる状況を作るには前もって「このプログラムはどのくらいの『メモリ』の場所を確保しておけばOKなのか」ということを何かで判断してその部分は確保しておかないといけません。
「適当に1GBくらいのメモリを確保しておけばいいんじゃないかなぁ」って考えてしまうかもしれませんがそれはあまりよろしくないのです。
簡単な処理しかしていないのに『メモリ』をめっちゃ使ってたり『CPU』にすごく負担をかけてしまうプログラムはクソ重くって使い物になりません。
『メモリ』も『CPU』も有限の資源なので「なるべくメモリを使用せず、なるべくCPUに処理をさせずに目的を達成する」というのが理想になります。
『メモリ』とは『ハードディスクドライブ』や『SSD』と同じように情報を0と1のバイナリデータというもので保存してくれる記録装置です。
しかし一点だけ大きな違いがあり、『ハードディスクドライブ』や『SSD』と違って『メモリ』は「通電している間しか情報を保存してくれない記録装置」となっています。
なので電源をオフにすると保存していたデータは綺麗さっぱり消えてしまいます。データが全て消えてしまう、というとなんか嫌な感じがしますね。
しかし、パソコン君やスマホ君に搭載されているOSやソフトウェアとかアプリケーションとかは永続的に記録させる必要のない情報はほぼ全て『メモリ』を使って一時的に情報を保持することで処理を実現しています。
何だか変な話ですね。壊れない限りずっとデータを保存してくれる『ハードディスクドライブ』や『SSD』とかの方が使い勝手が良さそうなのになぜ『メモリ』が使用されるのでしょうか。
その秘密は処理速度にあります。
今、著者の手元にある『HDD』の処理速度を見てみると約140MB/sくらいになってます。1秒間に140MBくらいの書き込みができる、という感じです。これは『HDD』の中でも結構早い方なのですが、ちょいと『メモリ』とくらべてみましょう。
『メモリ』はちょっと古いDDR3-1333というタイプでも12.8GB/sという桁違いな処理速度になります。
さらに昨今のPS4に搭載されている『メモリ』とかになると176GB/sというものすごい速度で処理ができちゃいます。比べ物にならないくらいの処理速度ですね。
なのでOSやアプリケーションなどでは基本的に処理が早い『メモリ』を主に使っていく形になっています。
あと永続的に記録させる必要のある情報って実はあんまり多くなかったりするのでそれも『メモリ』が使われる理由になっています。
使わない情報を識別して破棄するのって結構大変だったりするので、それなら最初から『メモリ』を使っちゃったほうが楽ちん、というわけですね。
さて、長くなりましたが話を戻しましてその『メモリ』をどのくらい確保する必要があるのか、という判定をしたりするときに『データ型』というのが使われます。
ちょっとサンプルを見てみましょう。以下は変数を『Int型』で定義した例です。
var n: Int // 変数『n』を『Int型』で定義します。
こうすると変数『n』は『Int型』で定義されるのですが、最近のMacパソコン(64ビットマシン)で構築したSwiftの『Int型』は『-9223372036854775808』から『9223372036854775807』までの数値を『8バイト』のデータ量を使って表現するように決められています。
つまり『メモリ』の領域を8バイト(64ビット)分確保しておけば変数『n』に関するメモリ周りの問題は発生しない、ということになりますね。
こんな感じで型をしっかり前もって定義してあげることで『ビルド』の時に必要なメモリ量を算出し、必要最低限のメモリだけ確保して実行してくれるプログラムを生成することができます。
あとコンピューターで使用されるほぼ全てのデータは『0』と『1』の集合であるバイナリデータなので、そのデータをどういう扱いにするのか、というところでも型が使われたりしますね。例えば『1001』をアルファベットの『a』として扱うのか、それとも数値の『1』として扱うのか、といったような感じです。
これは拡張子と同じような概念になります。拡張子が『.txt』ならばそのデータはテキストデータとして扱えば良いし、『.jpg』ならば画像データとして扱えば良いといった感じです。
『ビルド』とは『コンパイル』したり色々とこにょこにょ変換したりしてソースコードとかを実行可能な状態に変換することを指します。
これまでXcodeでSwiftを何度か実行させてきましたが、Xcodeではリアルタイムで簡単な『ビルド』を走らせてくれています。
『print()』とかを書いたらすぐ実行されている理由はこれです。
ちなみにXcodeのような高機能のエディタツール(SDK)を使用しないでプログラムを構築するとなると「ソースコード書く」 → 「コマンドとか打ってコンパイルする」 → 「確認する」 → 「続き書く」って流れになります。
ちょっと面倒くさそうな感じですが昔は全てそうやっていました。懐かしいですね。
『コンパイル』とは記述したプログラムのソースコードを機械語(0と1で構築されたプロセッサーが直接理解できるバイナリ)に変換することを指します。
『コンパイル』をしてくれるソフトウェアとかは『コンパイラ』と呼ばれます。
よく使用される言葉なので覚えておきましょう。
最近だと「型の指定が必要ない」という言語も沢山あります。有名どころだとJavaScriptとかPHPとかRubyあたりですね。
これはプログラマーが意識して型の指定をしなくてもソースコードを実行させるときとかコンパイルするときとかに裏側で上手く『メモリ』の操作をしてくれてるので実現できている感じになります。
この手の言語はさくっと処理が書けたり、初心者の方の学習コストが低いというメリットがありますね。
ただ、裏側で『メモリ』を操作する処理が余計に走るので実行速度が少し遅かったり、最低限必要となる以上のメモリが使われてしまっていたりしますので一長一短な感じになるかと思います。
さて、では大分長くなりましたが、最後にSwiftで使用する『データ型』について基本的な部分だけざざっと確認しておきましょう。
まず数値タイプの『データ型』です。正と負の整数を表現できる『データ型』は『Int型』になります。
これまでの記事で、直に数字を書いて数値を『print()』で出力していましたが、直に数字を書いた場合は内部的に『Int型』(Int64)として処理されています。
print(1) // 内部的に『Int型』として処理されてます。 var n: Int // 変数『n』を『Int型』で定義します。
文字列の場合は『String型』っていうのがよく使われます。
『データ型』を指定せず『"』で囲んで定義した文字列は内部的に『String型』として扱われているのでこちらも覚えておいて下さい。
print("Hello world") // 内部的に『String型』として処理されてます。 var s: String // 変数『s』を『String型』で定義します。
『true』とか『false』の『真偽値』の場合は『Bool型』が使用されます。直接書いた場合でも同じです。
print(true) // 内部的に『Bool型』として処理されてます。 var b: Bool // 変数『s』を『Bool型』で定義します。
「3.14」とか「0.12」とかの『浮動小数点数』(小数)を表現するために使用する『データ型』は『Double型』というやつになります。『浮動小数点数』は『Int型』だと表現できませんのでご注意下さい。
print(3.14) // 内部的に『Double型』として処理されてます。 var d: Double // 変数『d』を『Double型』で定義します。
Swiftで使用する基本的な『データ型』については以上です。このくらいをとりあえず抑えておけばなんとかなるかと思います。
『浮動小数点数』をコンピューターで扱うときははちょっと注意しなくてはならない事柄があります。ちょっと以下のサンプルをみてみましょう。
var n: Double = 0.21 var _n: Double = 0.20 print(n - _n)
変数についての細かい解説は次の記事で行いますが、上記のサンプルはただ「0.21 - 0.20」を行って出力するだけシンプルな処理です。答えは「0.01」になるはずなんですが、実行させてみるとあら不思議。
0.00999999999999998
変な数値が返ってきちゃいました。
これは10進数の『浮動小数点数』は2進数に上手く変換できないため、内部的に誤差が発生しちゃってるせいだったりします。
これは他の言語でも起こりますし、ずっと昔からコンピューター君は『浮動小数点数』の演算が苦手だったりします。内部的に全てのデータを0と1で管理しているコンピューターの世界ならではの問題点といった感じですね。
『浮動小数点数』は内部的に誤差が出る可能性があるということだけしっかり覚えておいて下さい。
というわけでめっちゃ長くなりましたが以上です。次の記事では『データ型』を意識しつつ『変数』とか『定数』とかについてやっていきましょう。ではではこの辺で失礼致します。
この記事は桜舞が執筆致しました。
著者が愛する小型哺乳類 |
桜舞 春人 Sakurama HarutoISDN時代から様々なコンテンツを制作しているちょっと髪の毛が心配な東京在住のプログラマー。生粋のロングスリーパーで、10時間以上睡眠を取らないと基本的に体調が悪い。好きなだけ寝れる生活を送るのが夢。ゲームとスポーツと音楽が大好き。誰か髪の毛を分けて下さい。 |
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。