17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

String?をアンラップせずに空文字か判定できるようにしてみた

Last updated at Posted at 2016-12-19

空文字判定の前にnull判定

文字列の空判定ってどの言語でも出て来ると思うんだけど、大体null判定した後に中身が空文字かどうかを精査しないといけない。

特にSwiftだと

型がStringなら

if !str.isEmpty {
	// 処理
}

で済む話なんだけど、String?だと

if str != nil && !str!.isEmpty {
	// 処理
}

ってやって Force Unwrap が出てくるのが気に食わない。(っていうか Java かよ←

if letを使って

if let str = str, !str.isEmpty {
	// 処理
}

って書くこともできて、アンラップした値を中の処理で使うなら良いんだけど使わない場合なんかもにょる。

そこで

(´-`).。oO(Optionalextension作ってやればよくね?

ってことでできたコードがこちら
StringExtension.swift
protocol StringOptionalProtocol {}
extension String: StringOptionalProtocol {}

extension Optional where Wrapped: StringOptionalProtocol {
    
    /// nilまたは空文字の場合trueを返す
    var isEmpty: Bool {
        if let str = self as? String {
            // アンラップに成功したので空文字か判定
            return str.isEmpty
        }
        
        // アンラップに失敗してるのでnilと判定
        return true
    }
    
    /// nilまたは空文字の場合falseを返す
    var isNotEmpty: Bool {
        guard let str = self as? String else {
            // アンラップに失敗しているのでnilと判定
            return false
        }
        
        // アンラップに成功したので空文字でないか判定
        return !str.isEmpty
    }
}

Stringに専用のプロトコルを用意してジェネリクスの型引数(Wrapped)に制約をかけているのがミソ。
こうすることでString?に対してだけこの中のメソッドを許可できる。
後は中でisEmptyisNotEmptyを実装してやればOK

※2019/7/30追記

ずっと放置していて忘れてたんですが、Swift4くらいのタイミングからwhereで直接型を指定できるようになっていました。

それに基づいて書き直したのがこちら
StringExtension.swift
extension Optional where Wrapped == String {
    /// nilまたは空文字の場合trueを返す
    var isEmpty: Bool {
        guard let str = self else {
            // アンラップに失敗してるのでnilと判定
            return true
        }

        // アンラップに成功したので空文字か判定
        return str.isEmpty
    }

    /// nilまたは空文字の場合falseを返す
    var isNotEmpty: Bool {
        guard let str = self else {
            // アンラップに失敗しているのでnilと判定
            return false
        }

        // アンラップに成功したので空文字でないか判定
        return !str.isEmpty
    }
}

呼び出し例はこんな感じ

func hoge(_ str: String?) {
	if str.isEmpty {
		print("empty string")	
	}
}

hoge("hoge")	// 何も出力されない
hoge("")		// "empty string"が出力される
hoge(nil)		// "empty string"が出力される

注意

  • 変数がnilの時と""の時で処理が変わる場合はこの方法は無意味なので用法用量を守って正しく使いましょう(
17
10
11

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?