isEmpty の方が count==0 よりも良い理由


前置き

Mediam から送られてきた Daily Digest の記事を理解の為に和訳して投稿します.

isEmpty の方が count==0 の方が良いというものです.

これはApple自体が推奨しているもので、この記事は実際に何でなのかを紐解いてます.

実行速度が早い

isEmptyはO(1)で実行されるのに対し、countはO(n)、つまり文字サイズに応じて実行速度が発生します.(n:stringの数)

実際の実行結果は

isEmptyは文字サイズに依存せず、実行速度もほとんど変化がないのに対して、countは文字数の増加と共に実行速度が上がっています.

可読性が高い

isEmptyVsCount.swift

let text: String = ""

if text.isEmpty {
  // 何かしらの処理
}

if text.count == 0 {
  // 何かしらの処理
}

と見比べた際に isEmpty の方が直感的に理解出来ます。

実際、文章にした際には

「もし文字列textが空白の場合」

「もし文字列textの文字数が0の場合」

という説明になり、日本語に落とし込んだ時に、前者の方が明らかに捻くれてないです.

可読性が高いですね。

isEmptyはOptional型のstringの際には注意

文字列がoptional型で指定されている場合にはisEmptyの利用に気をつけなくてはいけません.

optional型で僕が過去に読んだ記事

countの場合、そのまま利用出来ます

countExample.swift

let text: String? = ""

text?.count == 0 {
  print("処理成功(コンパイル通ります)")
}

isEmptyの場合は

wrong.swift

let text: String? = ""

if text?.isEmpty {
  //処理失敗(コンパイル通らない)
}

correct.swift

let text: String? = ""

//#1
//真偽を判定
if text?.isEmpty == true {
  print("処理成功(コンパイル通ります)")
}

//#2
if text?isEmpty ?? true {
  print("処理成功(コンパイル通ります)")
}

//#3
//強制アンラップ
//個人的に非推奨
//強制アンラップはoptional使ってる意味があまりなくなるので極力避けたいところ
if text!.isEmpty {
  print("処理成功(コンパイル通ります)")
}

//#4
//guard let で optionalの中身がnilじゃ無い場合returnされる
guard let nonNilText = text else {return}
//returnされた文字列が空かを確認する
if nonNiltext.isEmpty? {
  print("処理成功(コンパイル通ります)")
  print("nilでも空でもない時にprintされます")
}

引用元の著者は3番の強制アンラップを推奨していますが、僕はあんまり使いたくないです.

関数定義

isEmptyは「文字列の文字の有無をBooleanで返す」

countは「文字列に含まれる文字数(int)を返す」

ということで、空白を判定する場合にはcountを使うと遠回りになります.(実行速度の話と類似)

SwiftLintでこの構文避けれる

SwiftLintでisEmptyが最適な場合にERRORやWARNINGを出してくれます.

[引用](https://medium.com/better-programming/strings-comparison-isempty-vs-count-0-be80d701901b)

isEmptyの利用を統一させる上で Best Practice だそう.

まとめ

isEmptycount==0 よりも Apple では良いとされており、その理由は

  • 実行速度が速い
  • 可読性が高い
  • 関数の定義に準じている

といった理由になります.注意点としては

  • Stringがoptional型の場合はアンラップしてからじゃないとisEmptyは使えない

ということでした.

筆者もこれまで通り、isEmptyを意識してswiftを書いていこうと思う土曜日でした.