Help us understand the problem. What is going on with this article?

SwiftでKotlinのスコープ関数を作ってみた

More than 1 year has passed since last update.

スコープ関数

スコープ関数とは、関数を引数に取ることで、関数のスコープを変えることができる関数です。
Kotlinの標準ライブラリにある apply let run with also が当てはまります。
これを使うことで、1つのオブジェクトに対してたくさんの処理をしたいときに簡潔に記述できるようになります。
スコープ関数の使い方については以下の記事を参考にしてください。

Kotlin スコープ関数 用途まとめ

Swiftにはスコープ関数はない

今までKotlinをやってきて、今まさにSwiftをやっているのですが、Kotlinの let also を使えなくて、不便だと感じることがありました。
なので、SwiftのClosureを使って、let alsoと使えるようにしました。

ソースコード

import Foundation

// ------------------ let ------------------ 
protocol LetProtocol {}

extension LetProtocol {
    func `let`(_ closure: (Self) -> Void) {
        closure(self)
    }
}

extension NSObject: LetProtocol {}

// ------------------ also ------------------ 
protocol AlsoProtocol {}

extension AlsoProtocol {
    func also(_ closure: (Self) -> Void) -> Self {
        closure(self)
        return self
    }
}

extension NSObject: ApplyProtocol {}

let は、自身を引数として受け取った関数を実行します。
Kotlinの let と若干違う点は、Kotlinのほうでは関数を実行後に任意の型を返しており、返り値を設定してない場合は返り値がUnitが返っている点です。

also は、自身を引数として受け取った関数を実行しているところまでは letと同じで、異なるところは自身を返しているところです。

letの使用例

UserDefaultsに値を保存するとき

// ------------------ Before ------------------ 
UserDefaults.standard.set("aaaaaaa", forKey: "key1")
UserDefaults.standard.set("bbbbbbb", forKey: "key2")

// ------------------ After ------------------ 
UserDefaults.standard.let { it in
    // UserDefaultsのスコープ
    it.set("aaaaaa", forKey: "key1")
    it.set("bbbbbb", forKey: "key2")
}

alsoの使用例

コードでUILabelを作るとき

// ------------------ Before ------------------ 
let helloLabel = UILabel()
helloLabel.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
helloLabel.text = "Hello"
helloLabel.textColor = UIColor.red

// ------------------ After ------------------ 
let helloLabel = UILabel().also { it in
    // UILabelのスコープ
    it.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
    it.text = "Hello"
    it.textColor = UIColor.red
}

このUILabelをViewに追加するとき、わざわざhelloLabelのnamespaceを設定することなく、書くことができるようになります。

addSubview(UILabel().also { it in
    it.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
    it.text = "Hello"
    it.textColor = UIColor.red
})

スコープ関数を使ったメリット

  • スコープを絞ることができた
  • 1つのオブジェクトに対する処理{}内でまとめられた
  • コードがすっきりした
  • namespaceを省略して書くこともできる
taki4227
中小企業のSIer、ベンチャー企業を経て、今はSHOWROOMのエンジニアをしています。Android・iOS・Flutterでアプリ開発をしてきました。良いものを作って届けたい、良いものを作ることに携わりたい。
https://note.com/taki4227
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした