https://youtu.be/Grkd7Rzqj-M
今回も The Basics
の 整数
についてもう少し眺めていってみます。前回は固定長整数とそれを表す型の数々についてを見ましたけれど、今回はビット数を明示しない Int
型に着目していくことになりそうです。よろしくお願いしますね。
——————————————————————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #112
00:00 開始 00:17 前回のおさらい 01:06 Int 型 01:44 プラットフォームに依存するサイズ 04:06 Int を 64 bit と決め込むことについて 05:29 プラットフォームの差異を吸収する型 06:56 CGFloat と Double の相互運用 09:49 現存の 32 bit 環境 10:20 Apple Watch Series 3 11:21 電子決済アプリの対応状況 12:59 watchOS 上での CGFloat のサイズ 13:35 Apple Watch シミュレーターのインストール 16:07 CGFloat の検証コード 17:17 Int も CGFloat も 64 bit ? 17:38 Apple Watch シミュレーター上での Double と CGFloat の暗黙変換 18:38 Apple Watch シミュレーターの文字盤画面 19:44 Int 型の使いどころ 21:52 Swift における Int の扱い 22:53 32 bit 環境における Int の範囲 24:07 型エイリアス 25:26 同じ性質の型を独立して定義 26:24 IntMax 型の扱い 27:13 型エイリアスの使われどころ 31:01 関数型の型エイリアス 31:46 Int に窺う雰囲気のまとめ 32:22 UInt 型 32:57 ワードサイズ 34:35 汎用レジスター 38:17 クロージング ———————————————————————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #112
では、始めていきましょう。画面に映っているのは前回のお話が終わったスライドです。今回は「整数の境界」という形で、UInt8
やInt8
といった型の有限性についてお話ししました。Swiftには、8ビット、16ビット、32ビット、64ビットの符号付き・符号なしの整数型が用意されています。
今日は、一般的に使われる整数型、すなわちInt
型についての話をします。今まで紹介してきた整数型は、現代のコンピュータの原則に基づいて特定のサイズで決め打ちされた型でしたが、Swiftには特定のサイズを持たないInt
型もあります。Int
型は、プラットフォームによってそのサイズが決まります。具体的には、32ビットプラットフォームではInt32
と同じサイズ、64ビットプラットフォームではInt64
と同じサイズになります。
Swiftは多くの環境で動作することを目指している言語なので、32ビットプラットフォームも想定されています。The Swift Programming Languageの本には、32ビットプラットフォームではInt32
、64ビットプラットフォームではInt64
とだけ書かれていますが、16ビット環境で動かすSwiftが存在すれば、多分Int16
と同じサイズになるでしょう。そして、将来128ビットプラットフォームがあれば、Int128
も出てくるかもしれません。この部分はCPUがサポートするかどうかに依存します。
現在、iOSやmacOSのようなAppleのプラットフォームでSwiftを使用する限り、Int
型はInt64
と同じサイズで問題ありません。しかし、他の環境でビルドしたときにInt
が32ビットで困った経験がある人もいるかもしれません。そのため、厳密にサイズを指定する場合は、Int
の代わりにInt64
などを使う方が安心です。
ちなみに、C言語などではInt
のサイズが32ビットや64ビットに変わることで誤動作を引き起こすことがありましたが、Swiftではそのような問題が少ないことを期待しています。
また、フロート型(浮動小数点型)に関してはFloat
とDouble
が明確に分かれています。もともとは32ビットの方が速度的に有利だったため、用途によって使い分けがされていました。しかし、現在ではパフォーマンスがどちらもほとんど変わらなくなってきたため、どちらを使っても大差はないかもしれません。
アップルウォッチの第三世代が32ビットプラットフォームで動作するという話題が出ましたが、このように環境によって型のサイズが変わることを考慮し、適切に型を選択することが重要です。Swiftでは、将来的にもうまく対応してくれることを期待しています。
次回はさらに深い内容に踏み込んでいきたいと思います。以上で今回の話を終わります。 AT Flowや32bitの状況について話していますが、詳細はわかりませんね。検索できるかもしれないです。Apple Watchアプリは作っていないのですが、最初の頃には作ったことがあります。もう一度試してみてもいいかもしれません。Apple Watchアプリを作っている方がいれば、やってみようと思います。個人的にはあまり経験がないので、まずBuildが通るか試してみます。
Apple Watchアプリが欲しくなることが結構あります。対応していないアプリが多いのが現状です。電子決済についてですが、PayPayはApple Watch対応していますが、他の電子決済アプリは対応していません。電子決済が普及する前は、IDやクイックペイなどでApple Watchを使って決済ができたので、iPhoneを出す必要がなかったのですが、QR系決済が登場してからスマホを出さないといけなくなり、少し不便に感じます。QR決済ではクーポンがついてくることも多く、Apple Watchでは完結しないことが多いです。こうした点で、もう少し多くのアプリがApple Watchに対応してくれると助かりますね。
Apple Watchのインターフェイスコントローラーを使ったアプリ開発についても考えてみました。まずは、テキストを出すことで動作を確認してみます。シリーズ3のシミュレーターが必要なのかもしれませんが、準備に時間がかかりそうです。シミュレーターの設定やターゲットデバイスについても確認する必要があります。
後でシミュレーターを試してみて、実機で確認することも考えます。例えば、シリーズ2の実機などを使って試す予定です。具体的には、setUpWatch()
を追加してシミュレーションを行います。どのデバイスでもいいので、ペアリングをしてシミュレーションできるように設定します。
コンソールを使ってメモリレイアウトを確認します。32ビットか64ビットかを確認するために、CGフロート
やイント
のサイズを見てみます。確認の結果、64ビットのようです。この内容についてももう少し詳しく見てみる必要がありますね。 とりあえず、現時点での検証結果としては、基本的にSwiftのInt
型やCFloat
型が64ビットで動作していることが確認されました。なので、Swiftでは暗黙的な型変換もできるのではないかと思います。一応、この点についても確認してみましょう。
先ほどのビルド警告は、ただ立てなかっただけですね。具体的には、Apple Watch第3世代を仮定してみると、どのデバイスでも特に問題なく64ビットが使えるようです。つまり、簡単に32ビット環境をすぐに用意するのは難しそうですが、何か適した環境が見つかれば試してみようと思います。
さて、Apple Watchのシミュレーターを初めて動かしましたが、これはなかなか良いですね。iPhoneシミュレーターを初めて動かしたときに感動したのを思い出します。Apple Watchもとても可愛らしくて、たまにはApple Watchアプリでも作りたくなりますね。
本題に戻しますが、プラットフォームに応じてInt
のサイズが変わるという仕様が書かれていますが、Appleのプラットフォームに関してはあまり気にしなくても良さそうな印象です。また、特定サイズの定数型と異なる、このInt
型が存在する理由としては、一貫性と相互運用性を助けるためというメリットが挙げられています。
ただ改めて考えると、Int
型がどれくらい重要なのか疑問に思うこともあります。ソースコードを使い回すときに、プラットフォームに合った最適な速度で動くInt
型が提供できるなら、それは確かに便利です。特に32ビットプラットフォームでは、32ビットの数字で大体まかなえますよね。64ビットが必要な場面は特別な場合くらいでしょう。
例えば、膨大なデータを扱うAPIからデータを取ってきたときのIDが64ビットだったりする程度ですし、フォーループで32ビットを使い尽くすようなことは滅多にありません。それを考えると、32ビットプラットフォームで必要ない64ビットを使う必要がないというのは確かに利点です。
Swiftでは型推論と合わせてInt
型がうまく生きてきており、コードの一貫性や相互運用性に繋がります。なので、整数型を32ビットか64ビットか明確に選ぶ必要がない場面では、常にInt
型を使用するという基本的なルールが推奨されています。The Swift Programming Languageの本にもそのように記載されています。この方針に異論は少ないでしょうし、Int
型を使っていくのが良いと思います。
32ビットプラットフォームのInt
型の数値範囲についても触れておくと、-2,147,483,648から2,147,483,647までの値を格納できるため、これは多くの整数範囲に対して十分な広さを持っています。
少々話がそれますが、C言語では用途に応じて型エイリアスが用意されていましたね。例えば、ポインタや文字列の長さにはsize_t
型が使われます。SwiftでもインポートしたC言語の由来の型として使われているようです。こうした型の使い分けもまた、プログラムの一貫性や適応性に寄与するのだと思います。 ここでは、Swiftの型エイリアスや型定義に関する実践的な話題について触れています。最初に、型エイリアスの利用についての議論があります。Swiftでは型エイリアス (typealias
) を使って、既存の型に別の名前を付けることができますが、特定の状況では独自の型を定義する方が好まれる場合もあります。例えば、Int
型はそのまま使われることが多いものの、将来的には特定の用途に特化した型が独立して存在するかもしれません。
かつて、IntMax
型がタイプエイリアスとして Int64
に等しい形で定義されていた時代がありましたが、現在では廃止されています。その代わりに、ジェネリクスを活用して、例えば FixedWidthInteger
でより抽象的に型を扱うことが推奨されています。このように、便宜的なタイプエイリアスよりも、しっかりとした型を使う方向に変わってきています。
タイプエイリアスの利用法としては、コードの可読性や保守性を考慮して、名前が長いクラス名やライブラリ名を短縮するために使われることが挙げられます。あるプログラマーは、RxDataSources
というライブラリを用いる際に長いクラス名をローカルなタイプエイリアスで短くしており、例えば「RxDataSources.AnimatedSectionModelType」のような長い名前を短縮して使うことで、コードの見通しをよくしています。
一方、別のプログラマーは主にオブジェクトの中で使うときにタイプエイリアスを使っています。具体例として、String.Index
を使う際に単にIndex
とすることで、コードを簡潔にしています。
さらに、クロージャやコールバックハンドラーの定義でも、よくタイプエイリアスが使用されます。これにより、長くて複雑な型定義を簡潔に記述でき、コードの可読性が向上します。
最後に、型推論と組み合わせたInt
型の利便性についても話題になっており、この話は後ほど詳しく解説するとしています。
まとめると、Swiftではタイプエイリアスを使ってコードを簡潔にする一方で、特化した型を独立して定義することで汎用性と保守性を高める傾向が強くなってきていることがわかります。 とりあえずスライドを先に進めて、もう一つ整数型のお話のスライドがありました。UInt
(符号なしの整数型)というものが用意されているという話を前回しましたね。
不合な指定数だとして、現代のプラットフォームのワードサイズと同じサイズのUInt
型も提供されています。ここで「ワードサイズ」という言葉が出てきましたが、これは何かというと、Wikipediaによるとデータ量の単位を表現する言葉ですね。
ワードサイズというと、昔からプログラムをやっている人には馴染みのある言葉だと思います。しかし、実際に調べてみると、環境によってバイトサイズ自体もまちまちです。今では一般的には1バイト=8ビットですが、昔は7ビットが1バイトの場合もあったし、もっと半端なビット数が1バイトという環境もあったらしいです。
8ビットを正確に表す単位として「オクテット」という言葉もありますが、最近ではあまり使われない気がします。1オクテット、2オクテットといった感じですね。ワードサイズも同様にまちまちで、汎用レジスタのサイズをワードとして、その倍程度をダブルワード、半分をハーフワードと呼んだりします。私はダブルワードとハーフワードという言葉を初めて聞きました。
汎用レジスタのサイズをワードとするという話ですが、汎用レジスタとは何か説明しましょう。アキュムレータレジスタ、汎用レジスタ、スタックポインタなどがあります。汎用レジスタはCPUの中で直接演算できるレジスタです。
レジスタとは、変数のようなものだと思えば分かりやすいです。汎用レジスタは、もう少し便利な機能を持っていることが多いです。たとえばZ80というCPUには、アキュムレータレジスタの他にPCレジスタ、DEレジスタ、HLレジスタという16ビットのレジスタがあります。これらはアキュムレータレジスタの値を保存したり、演算に使ったりします。
とりあえず、ワードサイズとするという話です。ワードサイズが可変という環境もあるらしいですが、32ビットのプラットフォームでは32ビットがワードサイズ、64ビット環境では64ビットがワードサイズという感じで、Swiftではワードサイズという言葉を使っているようです。
結論として、Int
型やUInt
型を積極的に使っていくのがSwiftの流儀になります。次回はこのあたりを詳しく見ていきたいと思いますが、その前に浮動小数点数についても見ていくかもしれません。では、今日はこれで終わりにします。お疲れさまでした。ありがとうございました。