Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What is going on with this article?

More than 1 year has passed since last update.

@taki4227

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

スコープ関数

スコープ関数とは、関数を引数に取ることで、関数のスコープを変えることができる関数です。
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を省略して書くこともできる
5
Help us understand the problem. What is going on with this article?
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
5
Help us understand the problem. What is going on with this article?