0
0

More than 3 years have passed since last update.

スコープ関数のrun()関数を使わずに、ピリオドでメソッドを連結させる

Last updated at Posted at 2021-01-20

金田著「はじめてのandroidプログラミング 第5版」を使って、勉強しています。

 「第9章カウントダウンタイマーを作ろう」で使っているkotlinの文法のテクニックを解析してみます。
 スコープ関数のrun関数を関数式に直してみます。
 はじめはrun関数の意味が分からなかったので、まずはrun関数を使わず、インスタンスを作り、そのメソッド()を一行1行、操作する古いやり方に書き換えようとしました。しかしSoundPoolクラスのコンストラクタが非推奨になっていたので、本書のとおりSoundPool.Builder()でインスタンスを作ることにしました。調べて行く過程でrun関数を使わずに、ピリオドでメソッドを連結できることが分かったので紹介します。

 以下、本書を持っている前提で説明します。本書を使って勉強中の方、一緒に勉強しましょう。

0.前提

 p253まで写経が済んでいるとします。

1.原型

 p253まで写経が済んでいる状態のコードを示します。説明に不要な部分は、著作権に配慮して省略しています。
 本書のやり方では、SoundPool.Builder()のrun()関数の中に、AudioAttributesのインスタンスを作り出すAudioAttributes.Builderが含まれています。

MainActicity.kt
class MainActivity : AppCompatActivity() {
    // 省略
    override fun onResume() {
        super.onResume()
        soundPool =
                SoundPool.Builder().run {
                    val audioAttributes = AudioAttributes.Builder().run {
                        this.setUsage(AudioAttributes.USAGE_ALARM)
                        this.build()
                    }
                    this.setMaxStreams(1)
                    this.setAudioAttributes(audioAttributes)
                    this.build()
                }
        // 省略
    }
    // 省略
}

2.AudioAttributes.Builderを、SoundPool.Builder()のrun関数の外に出す

 先ずは、SoundPool.Builder()のrun関数の中に含まれているAudioAttributes.Builderを、SoundPool.Builder()のrun関数の外に出します。なおrun関数の動作については、本書p127に書かれています。

MainActicity.kt
class MainActivity : AppCompatActivity() {
    // 省略
    override fun onResume() {
        super.onResume()

        val audioAttributes = AudioAttributes.Builder().run {    // (2)(1)をここへ移動する。(追記)
            this.setUsage(AudioAttributes.USAGE_ALARM)    // this.は省略可
            this.build()
        }

        soundPool = SoundPool.Builder().run {
            // val audioAttributes = AudioAttributes.Builder().run {    // (1)この部分を外に出す(削除)
            //    this.setUsage(AudioAttributes.USAGE_ALARM)
            //    this.build()
            // }
            this.setMaxStreams(1)
            this.setAudioAttributes(audioAttributes)
            this.build()
        }
        // 省略
    }
}

 ここで、 AudioAttributesクラスやSoundPoolクラスのインスタンスを作るのに、コンストラクタを用いることが非推奨であるから、AudioAttributes()やSoundPool()といった風にコンストラクタを使えないので、このままAudioAttributes.Builder()、SoundPool.Builder()を使ってインスタンスを作ることとした。

3.ピリオドで連結する方法に変換する

 上記のコードをピリオドでメソッドを連結した形式に書き換えます。ピリオドで連結する形式に変換するにあたり、nyan のアプリ開発を参考にした。

MainActivity.kt
// 省略
    override fun onResume() {
        super.onResume()

        // 変換方法<参考> https://akira-watson.com/android/kotlin/soundpool-play.html>
        val audioAttributes = AudioAttributes.Builder()    // run()関数とthisを外し、関数をピリオド(.)連結する。
            .setUsage(AudioAttributes.USAGE_ALARM)
            .build()
        // val audioAttributes = AudioAttributes.Builder().run {    
        //     this.setUsage(AudioAttributes.USAGE_ALARM)    
        //     this.build()
        // }

        // 変換方法<参考> https://akira-watson.com/android/kotlin/soundpool-play.html>
        soundPool = SoundPool.Builder()    // run()関数とthisを外し、関数をピリオド(.)連結する。
            .setMaxStreams(1)
            .setAudioAttributes(audioAttributes)
            .build()
        // soundPool = SoundPool.Builder().run {
        //     this.setMaxStreams(1)
        //     this.setAudioAttributes(audioAttributes)
        //     this.build()
        // }

        // 省略
    }

// 省略

 ピリオドで連結する形が使えるのは、AudioAttributes.BuilderクラスやSoundPool.Builderクラスのメソッドの戻り値が、AudioAttributes.Builder型やSoundPool.Builder型であるからである。例えばAudioAttributes.BuilderクラスのメソッドsetUsage()は、戻り値の型がAudioAttributes.Builderである。setUsage()のリファレンスを参照して頂きたい。

 さて、第2項のrun()関数を使うやり方と第3項のピリオドで連結するやり方とでは、どちらが見やすいでしょうか?私は、電車ごっこのような、順繰りとタスクが進むピリオドで連結する方が、分かりやすく見やすいと思います。run関数を使うか、関数式を使うかの選択は、趣味の問題でしょうか?疑問が残ります。

4.ピリオド連結を分解し、メソッドを一行一行処理する(2021/01/21追記)

 当初やり方が分からなかったが、落ち着いて考えたら方法を思いついたので記述する。
 ピリオドで連結していたメソッドを分解し、一行一行に変数を設けるようにコードを書き換える。

MainActivity.kt

        //   val audioAttributes = AudioAttributes.Builder()
        //       .setUsage(AudioAttributes.USAGE_ALARM)
        //       .build()
        val buildedAudioAttributes = AudioAttributes.Builder()
        val setUsagedAudioAttributes = buildedAudioAttributes.setUsage(AudioAttributes.USAGE_ALARM)
        val audioAttributes = setUsagedAudioAttributes.build()

        // soundPool = SoundPool.Builder()
        //    .setMaxStreams(1)
        //    .setAudioAttributes(audioAttributes)
        //    .build()
        val buildedSoundPool = SoundPool.Builder()
        val setMaxStreamsedSoundPool = buildedSoundPool.setMaxStreams(1)
        val setAudioAttributedBuildedSoundPool = setMaxStreamsedSoundPool.setAudioAttributes(audioAttributes)
        soundPool = setAudioAttributedBuildedSoundPool.build()

        // 省略

5.蛇足

 見た目、汚らしいですがrun()関数の中で、メソッドを連結することも出来るみたいです。第2項、第3項と比較してください。

【例1】

MainActivity.kt
        soundPool = SoundPool.Builder().run {
            setMaxStreams(1)
                .setAudioAttributes(audioAttributes)     // ここから先を関数式で連結
                .build()
        }

 
【例2】

MainActivity.kt
       soundPool = SoundPool.Builder().run {
            setMaxStreams(1)
            setAudioAttributes(audioAttributes)
                .build()     // これだけを関数式で連結
        }

0
0
0

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
0
0