10

したがって、拡張メソッドと拡張プロパティが本当に静的なメソッドとプロパティである場合。また、静的メソッドとプロパティとメソッドはスレッドセーフではないため、避ける必要があります。拡張メソッドと拡張プロパティは良くありません。

私たちが書いたコードはきれいできれいに見えますが、パフォーマンスに関してはそうではないため、私たちはそれらを行うようにだまされています.

これは本当ですか?

4

3 に答える 3

13

拡張関数/プロパティの書き方によって異なります。彼らが共有状態を編集またはアクセスしない場合、つまりプロパティと関数が明確な関数である場合: それは絶対に悪い習慣ではありません。

例 1:

fun String.countSpaces(): Int {
    return this.count { c -> c == ' ' }
}

Stringこの関数は不変であるため、マルチスレッド環境で完全に機能します。

例 2:

data class MutablePerson(val name: String, var speech: String)

fun MutablePerson.count(nextNumber: Int) {
    this.speech = "${this.speech} ${nextNumber}"
}

この関数speechはオブジェクトのプロパティを変更MutablePersonし、代入操作はアトミックではありません。異なるスレッドから 1 つのオブジェクトに対して呼び出される場合count- 矛盾した状態になる可能性があります。

例:

fun main(args: Array<String>) {
    val person = MutablePerson("Ruslan", "I'm starting count from 0 to 10:")

    (1..10).forEach { it ->
        Thread({
            person.count(it)
            println(person.speech)
        }).start()
    }

    Thread.sleep(1000)

    println(person.speech)
}

可能な出力:

I'm starting count from 0 to 10: 1
I'm starting count from 0 to 10: 1 3
I'm starting count from 0 to 10: 1 3 4
I'm starting count from 0 to 10: 1 3 4 2
I'm starting count from 0 to 10: 1 3 4 2 5
I'm starting count from 0 to 10: 1 3 4 2 5 8
I'm starting count from 0 to 10: 1 3 4 2 5 6
I'm starting count from 0 to 10: 1 3 4 2 5 6 7
I'm starting count from 0 to 10: 1 3 4 2 5 6 7 9
I'm starting count from 0 to 10: 1 3 4 2 5 6 7 9 10
I'm starting count from 0 to 10: 1 3 4 2 5 6 7 9 10

したがって、拡張関数と拡張プロパティは悪い習慣ではありません。クラスのプロパティとメソッドに似ています。記述方法に応じて、スレッドセーフかどうかによって異なります。

于 2016-11-14T23:34:59.747 に答える
9

静的メソッドには、インスタンス メソッドと同様に独自のスタックがあります。したがって、静的メソッド内の一時変数は、インスタンス メソッドと同様にスタック上にあります。静的メソッドに渡されるパラメーターは、共有状態にアクセスするときにスレッド化の問題が発生する可能性がありますが、これはインスタンス メソッドの場合とまったく同じ状況です。

Java には拡張機能がないため、静的メソッドを使用する Java の膨大な量の Util クラスを考えてみてください。マルチスレッドに関しては、何も問題はありません。

また、C# の拡張メソッドは舞台裏の静的メソッドであり、害はありません。「拡張メソッドが内部で実装される方法」を参照してください。

于 2016-11-15T07:32:50.423 に答える