これは初学者である筆者が初めてcompare
と出会った時の思考を綴るものとなっております。
ここでいうcompareはSwiftのStringクラスインスタンスメソッドcompare
を指します。
compareの返り値って何なの問題
ComparisonResult
ですね。はい、おしまい。
・・・とならないのが初学者です。
私ももれなくその一人でした。
AppleDeveloperドキュメントにも、目立つくらい**Return Value
**って書いてあるのに!
そんな初歩的なところでつまづいている訳ですが、試行錯誤の過程は良い勉強になったのでこちらにアウトプットという形で残すことにしました。
どこで出会ったのか?
Swift実践入門 第3版 P53
Foundationによる高度な操作 見本コードにて
上記箇所となります。
swiftの学習にと、こちらの書籍を手に取る初学者の方も多いのではないでしょうか。
私は上記箇所で突然現れた次のコードをみて固まってしまいました。
// P53 見本コード
import Foundation // compareはFoundationというライブラリで提供されているメソッド
// 2つの文字列間の順序の比較
let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("ABC", options: options)
order == ComparisonResult.orderedSame //true
上記のコードでは、compare(_:option)メソッドで2つの文字列間の順序を検証しています。
--略-- 結果として順序が同じであることを意味する.orderSameという値を得ています。
一読しただけではよく分かりませぬ。
コードリーディングしてみる
まず1行目
let options = String.CompareOptions.caseInsensitive
これはConpareメソッドに用意されているオプションで、大文字と小文字を区別しないというもの。
これを定数optionsとして定義している。
2行目
let order = "abc".compare("ABC", options: options)
右辺では、文字列"abc"に対してcompareメソッドを使用し()内の"ABC"との比較をしている。その際、引数として先ほど定義したoptions
を受け取っている。
ここで得られた結果を、定数order
として定義している。
3行目
order == ComparisonResult.orderedSame
2行目で定義したorder
とComparisonResult.orderedSame
を比較演算子にかけ、trueが返ってくる。
細かな内容について考えてみる
上記を踏まえ少しコードを簡素にした。
オプションについては疑問点とは関係なさそうなので省略。
let order = "abc".compare("abc")
order == ComparisonResult.orderedSame // true
つまり、"abc".compare("abc")
の返り値はComparisonResult.orderedSame
ということ?
確認してみた。
let hoge = "abc".compare("abc")
print(hoge) // NSComparisonResult
実行結果・・・NSComparisonResult
ComparisonResultとは
見本コードでも何食わぬ顔で現れたこいつを理解する必要がありそう。
調べてみるとComparisonResult
は列挙型で、3つのcase定数を持つということが分かった。
enum ComparisonResult: Int {
case orderedAscending = -1
case orderedSame = 0
case orderedDescending = 1
}
ということはcompareメソッドはcaseのどれかを取得した後、ComparisonResultを返すということになると考えられる。
- case orderedAscending ・・・
<
- case orderedSame ・・・
=
- case orderedDescending ・・・
>
今回は比較対象がイコールであったため、orderedSame
という値を取得し、
ComparisonResult.orderedSame
が返されたということになります。
compareの返り値
ということで冒頭のコードに戻ってみる。
せっかくなので、"ABC"だったところを"DEF"に変えてみる。
let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("DEF", options: options)
order == ComparisonResult.orderedAscending
// true
2行目の"abc".compare("DEF", options: options)
の返り値がComparisonResult.orderedAscending
なのでtrueということとなる。
abc < DEF
という比較結果となっています。
後語り
今、自分で書いていても、「なぜこんなことが気になったのだろう?」と感じてしまうような内容ですね・・・
思いつく理由としては、メソッドの返り値が列挙型
ということに戸惑いがあったからなのかもしれません。
別のメソッドですが、以下のようなシンプルな挙動をイメージしていました。
私が期待していたようなコード及び実行結果
// 私が期待していたようなコード及び実行結果
"abc".isEqual("abc")
// true
今回も上記のような形が頭から離れず「比較系メソッドはtrue/falseが返り値となるものだ」という先入観により、つまづき理解に苦しんでしまいました。
結論:さっさと公式ドキュメント読めばよかった。
おしまい。
ここまでお読みくださりありがとうございましたm(__)m