LoginSignup
6
4

More than 5 years have passed since last update.

SwiftでKotlinのletのようなもの

Last updated at Posted at 2017-05-31

KotlinがGoogleさんに認められた(?)ので、Kotlinを勉強し直さないとと思い、記事を読んでいたらletという機能があると...
結構便利そうなのでSwiftでもできないかなーと

読んでた記事
↓↓↓↓↓↓↓
JavaプログラマがKotlinで便利だと感じること

Kotlinのlet

たとえば、数を足すだけのメソッドfooがありますよと
そのfooを複数回使う計算とかでてきますよね...

(foo(1, 2) + 6) / foo(1, 2) // 3

こんな感じ
どっちのfooも引数が同じなので、返り値も同じですね
そうなると無駄ではw(fooがもっと重い処理になったら複数回も呼びたくないとw

とりあえずの解決策

val f = foo(1, 2)
(f + 6) / f // 3

とりあえず、fooは1回しか呼ばなくてすみましたね
でも、2行になってしまったよ...(細かいですがw

そこでlet

foo(1, 2).let { f -> (f + 6) / f }

1行だし、1回しかfoo呼んでないしいい感じ
とりあえず、letの実装を...

inline fun <T, R> T.let(block: (T) -> R): R = block(this)

呼び出し元をClosureにいれるのか!ふむふむ

Swiftでやっちゃおう

まず、名前がかぶるのでletが使えない(みなさんご存知、変数宣言時のletがありますねw
なので、letsにしました(let_swiftの略みたいな感じです

とりあえず、実装を!

// プロトコルを定義
protocol Lets {}

// プロトコルにメソッドを追加
extension Lets {
    func lets<R>(_ closure: (Self) -> R) -> R {
        return closure(self)
    }
}

// プロトコルを拡張したいクラスに
extension Int: Lets {}

プロトコルとして定義して、そのプロトコルでクラス(今回はInt)を拡張します
使い方は、この通り簡単です

foo(1, 2).lets({
    ($0 + 6) / $0
}) // 3

改善できなかった点

Swiftに全ての元になるクラスがみつからなかったため、使うクラスに随時拡張していかなくてはならなそうでした....

追記

演算子を使用して...と、コメントでいただきましたので、みなさんのお役に立てればと!
=>演算子を使用しています

foo(1, 2) => {
    ($0 + 6) / $0
}

詳細はこちらのGitHubにあります。

まとめ

今回紹介したクラス拡張の仕方は、きっとどこかで役に立つと思うのでぜひぜひ覚えてください。
今回はIntクラスに拡張しましたが、他のクラスでもできますのでみなさんもお試しください:sunglasses:

GitHub Gist

参考

SwiftでKotlinのapplyっぽいものを使いたい
(こちらで紹介されているapplyも役に立つ、使いやすいので是非お試しください)

6
4
2

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
6
4