https://youtu.be/k-_zLEubgE0
今回は The Basics
の コメント
について見ていきます。Swift でのコードにコメントを記載する方法について見ていくというシンプルな回になりそうですけれど、せっかくの機会なので改めておさらいしてみましょう。それをみ終わった後は、こちらもお馴染みな人が多いかもしれない セミコロン
についても眺めてみようと思っています。どうぞよろしくお願いしますね。
———————————————————————————— 熊谷さんのやさしい Swift 勉強会 #108
00:00 開始 00:43 コメント 01:08 自分自身への備忘録として利用できる 04:05 C 言語とよく似たコメントの書き方 06:12 コメントとドキュメントコメント 07:29 コメントを書いてみる 07:52 コメントはどこまで必要か 08:56 コメントの添え方について 11:07 関数定義をコメントとして使う 12:30 構造化プログラミングで意味を加える 13:55 オブジェクト指向プログラミングで意味を加える 15:15 Swift では名前空間を活用 15:58 メソッドにするか計算型プロパティーにするか 16:33 計算量と API デザインガイドライン 19:35 Apple の選び方を観察してみる 23:48 コメントの在り方に感じる変化 26:13 迷ったらメソッドという選択 26:53 C 言語のコメントとは違うところ 27:29 Playground マークアップ 33:35 C 言語で見られたバグ 35:36 ドキュメントコメント 37:07 コードとコメントの整合性が課題 38:54 次回の展望 ————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #108
はい、じゃあ始めていきますね。今日はとてもシンプルな題材、コメントについて見ていく回になります。今まででコメントってAPIデザインガイドラインの話をしたとき以外に出てきたかな?あんまり記憶に残っていないですが、ちょっと見ていけば思い出せるかもしれないですね。それか本当に初めてか。とりあえず見ていきましょう。
コメントの話はとてもシンプルで、本当に素直に「コメント」というものがあるよっていう回になります。さっそく見ていくと、コード内に実行されないテキストを含めるためにコメントが使えると書いてありました。そのとおりですよね。コメントは自分自身へのメモや備忘録として利用できると書いてありましたけど、確かにその通りですが、最近は自分自身へのメモや備忘録としてコメントを書くことはあまりしなくなっているような気がします。
なぜかというと、関数名や変数名が丁寧に書かれるようになったり、オブジェクト指向により機能と値が一箇所にまとまっているため、コメントを備忘録として使う必要が少なくなったからかもしれません。でも、イレギュラーな箇所にコメントを入れるときはありますね。そういったものを備忘録として利用するのかな?ToDoコメントも確かに使いますね。未来の自分に向かって書いていると考えると、これはメモや備忘録に該当しますね。
また、SwiftLintなどのツールに対する指示としてコメントを書くこともありますね。こういったコメントの使い方も確かにあります。自分が感じていた違和感は、コメントを自分自身へのメモとして利用するということに対してだったかもしれません。
さて、コメントの書き方について見ていきましょう。SwiftのコメントはC言語のコメントととてもよく似ています。C言語スタイルのコメントの書き方が採用されています。単一行のコメントと複数行のコメント、この2つの書き方が用意されています。
- 単一行のコメントは
//
で始まります。 - 複数行のコメントは
/*
で始まり、/
で終わります。
C言語やその系列の言語に慣れている人にとっては、とても当たり前の書き方です。また、JavaDoc形式で関数についてコメントを書き、それをAPIのドキュメントとして利用する方法もSwiftには含まれています。
最近は、コメントはドキュメントを整備するため、つまりAPIを使う人のために書くことが多いです。そのため、自分自身のためというよりは他の人のためにコメントを書くイメージが強く、これが違和感の元だったのかもしれません。
ドキュメントコメントという言葉もあり、それと通常のコメントの間でイメージが違ってきます。ToDoやイレギュラーな部分に関してもドキュメントコメントになり得るため、境目は曖昧ですが、役割が異なることも多いですね。
今お話しているのは大きな意味でのコメントで、その中の一部がドキュメントコメントとして存在する感じです。
まず、プレイグラウンドで遊んでみますか。コメントの書き方はとてもシンプルですが、例えば1行コメントの場合は //
を使います。
// これは1行コメントです
複数行コメントの場合は以下のように書きます。
/*
これは複数行コメントです
2行目
3行目
*/
昔はコメントを書くことが重要でしたが、今の状況では関数や変数名、コードの構造が分かりやすくなっているため、コメントなしでも理解できることが多いです。しかし、複雑な処理や一時的なもの、特別な指示がある場合にはコメントを使って補足することが有用です。 例えば、昔の手続き型言語を使って配列の合計を計算したい場合、以下のようなコードを書いていました。
var sum = 0
for value in values {
sum += value
}
print(sum)
このようなコードは、昔ながらの手続き型言語(例:BASICやアセンブラなど)ではよく見られるものでした。複数の行を使って、何をやっているかをコメントで説明するスタイルです。
最近では、このような手続き型の書き方から、コードの可読性や再利用性を高めるために、関数やプロパティを活用したオブジェクト指向的な書き方へ移行しています。例えば、以下のように書きます。
func sumOfValues(_ values: [Int]) -> Int {
var sum = 0
for value in values {
sum += value
}
return sum
}
let values = [1, 2, 3, 4, 5]
print(sumOfValues(values))
このようにすることで、sumOfValues
関数に説明的な名前を付け、何を計算しているかが明確になります。さらに、Swiftでは拡張機能を使用して、より自然なコードを記述できます。
extension Array where Element == Int {
var sum: Int {
var total = 0
for value in self {
total += value
}
return total
}
}
let values = [1, 2, 3, 4, 5]
print(values.sum)
こちらのコードでは、Array
型に対してカスタムプロパティsum
を追加しています。このプロパティを使うと、配列そのものに合計を計算する機能が内包されていることが明示され、コードはより直感的になります。
このように、手続き型言語のスタイルからオブジェクト指向もしくは関数型のスタイルに移行することで、コードの可読性や再利用性が大きく向上します。Swiftでは、拡張機能や計算型プロパティを活用することで、非常にエレガントで読みやすいコードを書くことが可能です。 ただ、sum
を関数として定義するか、今みたいに計算型プロパティとして定義するか、ここは評価が分かれてきそうな気がします。APIデザインガイドラインの場合、オーダー1のものはプロパティとして作るけど、そうじゃない場合は関数にする、またはコメントに「計算量が多いですよ」としっかり書くように指示されています。しかし、ここでは要素の数に応じて処理数が変わってくるので、これを関数にすべきかプロパティにすべきか、どっちが主流なんでしょう。自分はプロパティにしそうな気がしますが、みなさんはどう思いますか?
APIデザインガイドラインでプロパティにするためには、複雑度がO(1)じゃないとダメという記述があった気がします。具体的には、複雑度がO(1)じゃないときにはコメントに書くように推奨されていますね。他にどっちが好ましいという意見はありますか?
イメージ的な話ですが、計算しているので関数かなと思いますね。単純なプロパティアクセスはO(1)かどうかはコメントで説明しますが、計算が入る場合、例えば足し算くらいのロジックであれば関数にしたいという気持ちになりますね。ただし、根拠はありません。イメージとして関数を実行しているという予感があります。
確かに複雑な計算型プロパティの場合は、ドキュメントに「O(1)じゃない」と説明する必要がありますね。その理由としては、ユーザーがプロパティをアクセスする際に即座に結果が返ると期待するからです。それを注意喚起するためにも、コメントにしっかり書いてあげる必要があります。
Appleのドキュメントでは、例えばsum
は関数として定義されています。ただ、プロパティとしても関数としても使われることがあり、統一されていません。また、標準ライブラリやファウンデーションなどによっても雰囲気が異なります。max
も関数として用意されています。
プロパティとメソッドの分類についても触れておくと、カウントはプロパティで定義されています。例えば文字列のカウントもプロパティで提供されています。カウントプロパティは内部で効率的に取得できるようになっているためですが、これは適宜ドキュメントを参考にするべきです。Collection
のカウントについてもドキュメントで説明されています。
まとめると、APIデザインガイドラインに準じるなら、オーダー1でないものをプロパティにする際にはしっかりコメントを残すのが推奨されます。また、関数として定義するかプロパティとして定義するかは、ケースバイケースで判断すべきということになりますね。 今お話しした内容に戻りますが、ランダムアクセスコレクションにおいては時間計算量が O(1)、それ以外では O(n) になるという記述がコメントにちゃんとされているため、プロパティでも問題ないということですね。
さて、さっきの max
についてどうなっているか見てみましょう。max
がどこにあるのかというと、コレクションではなく Array ですね。Collection
には max
がありません。Array
にはあります。関数ですので、ガイドライン的には問題ありませんが、ちゃんと O(n) と書いてありますね。これがもしランダムアクセスコレクションの場合、もしかすると O(1) になる可能性があるのなら、プロパティになっているかもしれません。その辺りは関係ないかも知れませんが、確かに max
のようなものはプロパティではなく関数の方がしっくりくるかもしれません。
続いて、今定義した sum
や values
、average
も関数の方が直感的でわかりやすいかもしれませんね。例えば、sum
はプロパティで作りましたが、なんとなく関数の方が良い気がしてきます。際どいところですが、average
は関数であるべきだと思います。
さて、コメントについてに戻りますが、コメントを書く方法が今は多様になってきています。これにより、コメントを書く機会も増えました。そのため、コメントの役割も、単なるメモからより意味のあるものへと変わってきました。他の人やコンピュータに通知するための役割を持つコメントも増えています。
スライドに戻りますが、「実行されないテキスト」としてのコメントは、何らかの形で実行される、つまり無意味ではなくなってきています。単に自分のためではなく、他の人のためにも役立つものとなってきています。
また、質問に対して「迷うならメソッドで」とのコメントがありましたが、これも非常に有用なアドバイスです。プロパティに偏らせると、色々と問題が生じることがあるため、メソッドにしておく方が平和だということですね。
次に、コメントを見ていきます。Swiftのコメントは、C言語のコメントと非常に似ています。しかし、具体的にどこが違うのかと問われたときに思い浮かぶのが、Playground専用のコメントなどですね。専門の言葉が確かにあったような気がしますが、忘れてしまいました。 とりあえず、Playgroundに対して「ここはどういう意味のコメントですよ」みたいに書いておくことで、さまざまな効果を発揮します。普通のコメントと比べると、Playgroundとしてのコメントを使い分ける機能ですね。これによってPlaygroundで手軽にサンプルを作ることができます。
一時期こういうのを使って書いている人を見かけましたが、最近はあまり見ないですね。自分が見つけられていないだけかもしれませんが。Swift学習用のドキュメントやプロジェクトをPlaygroundで作る方っていますかね?これが便利なのかはちょっと分からないですが。他にも「NextPage」といった機能がありましたね。ソースの説明で使われているのを見たことがあります。確か、RxSwiftは結構しっかり作っていた気がします。
ページを分けてリンクする機能もあって、ちゃんとページごとに作られていました。「Next」とかもあった気がします。ビルド前のPlaygroundで何を確認するのが大事で、ドキュメントとして使うのも確かに便利ですが、ちゃんと書くのが難しいかもしれません。
ここでPlaygroundをダウンロードしてみましょう。これでクローンすればいいですね。ここはRxPlaygroundです。Playgroundを開いているように見えないですが、ページフォルダにソースが入っているようです。このようにリンクをたどれる機能があって、Playgroundページの名前を指定しておくとリンクをたどれるようになっています。ほんとうにすごいですね。
例えば、ページ番号が「10」の次が「1」になるバグがあったりします。これはお粗末なバグですが、適当に作っている感じがします。Appleの人も普通だったらきちんとインクリメントするように実装するはずですが、もしかするとゼロとドットがオーバーフローして隠されているのかもしれません。おそらくスタイルシート的な問題かなと思います。
このようにMarkdownに近い形で記述すると、適切に表示されるようになります。このようにコメントを加工して付加価値をつけることで、コメントを活用する流れができてきていますね。 C言語だと、コメントを消すと動かなくなることがあります。そんなことがあるんですね。限定的な状況では、Shift JISか何かで保存して、LinuxのGCCでコンパイルすると開業文字を含むコメントの最終行が次の行を無効にすることがあります。なるほどね。確かにそれはコメントとは違う事例ですが、似たような問題として心当たりがあります。たとえば、正規表現の時にも、Shift JISだと文字コードの問題で円マークと同じコードが入ってしまい、特殊文字として解釈されておかしくなることがあります。同じようなノリですね。
他にも、E言語など特定の言語環境によって動きが異なる場合があり、そこにコメントを使って付加情報を埋めておくことがあります。どのプログラミング言語か忘れましたが、そんな事例もありますね。コメントを特別な用途で使うことがC言語と少し違うポイントです。
ドキュメントコメントについても触れましょう。今回のスライドには出てこないかもしれませんが、普通のコメントだけを書くと人間にはわかる程度の説明になります。しかし、ドキュメントコメントを使うと、たとえば.sum
と入力したときに説明がポップアップで表示されます。これは、///
で始まるドキュメントコメントでPlaygroundやクイックヘルプなどに表示されるため、非常に便利です。
コードコメントには、その正確性をテストする手段がないので、避けられるなら避けたほうが良いという話もあります。たとえば「このコードは合計を計算します」とコメントを書いても、将来的にコードとコメントが食い違った場合、誤解を招く可能性があります。コメントを書かなくても済む場合、避けるのが良いかもしれません。
コメントについて意識して書くと、うまく扱えるようになります。C言語とSwiftのコメントの大きな違いについてはまだ紹介しきれていませんが、時間となりましたので、そのあたりは次回お話ししたいと思います。今日はここまでとしましょう。勉強会お疲れ様でした。ありがとうございました。