properties - لبرمجة - كوتلن حسونه



هل هناك ديسيت/ويلسيت التناظرية في كوتلين؟ (1)

على الرغم من أن كوتلين لا توفر المدمج في حل على غرار سويفت لملاحظة التغييرات الملكية، لا يزال بإمكانك القيام بذلك في عدة طرق اعتمادا على ما هو هدفك.

  • هناك observable(...) مندوب (في ستدليب) الذي يسمح لك للتعامل مع التغييرات الملكية. مثال الاستخدام:

    var foo: String by Delegates.observable("bar") { property, old, new ->
        println("$property has changed from $old to $new")
    }

    هنا، "bar" هو القيمة الأولية للعقار foo ، ويسمى لامدا في كل مرة بعد تعيين الخاصية، مما يسمح لك لمراقبة التغييرات.هناك أيضا vetoable(...) المفوض الذي يسمح لك لمنع التغيير.

  • يمكنك استخدام الإعداد المخصص لعقار لتنفيذ أوامر تخريبية قبل / بعد تغيير القيمة الفعلية:

    var foo: String = "foo"
        set(value: String) {
            baz.prepareToDoTheThing()
            field = value
            baz.doTheThing()
        }

    كما أشار كريلرخمان ، هذا الحل هو فعال جدا لأنه لا يقدم النفقات العامة في طريقة المكالمات والأشياء، على الرغم من رمز سوف تكون مكررة قليلا في حالة العديد من الخصائص.

  • بشكل عام، يمكنك تنفيذ مندوب الممتلكات الخاصة بك، صراحة توفير سلوك الملكية في getValue(...) و setValue(...) .

    لتبسيط المهمة الخاصة بك، استخدم ObservableProperty<T> الفئة المجردة التي تسمح لك لتنفيذ المندوبين الذين يراقبون التغييرات الملكية (مثل observable و vetoable أعلاه) مثال:

    var foo: String by object : ObservableProperty<String>("bar") {
        override fun beforeChange(property: KProperty<*>, oldValue: String, newValue: String): Boolean {
            baz.prepareToDoTheThing()
            return true // return false if you don't want the change
        }
    
        override fun afterChange(property: KProperty<*>, oldValue: String, newValue: String) {
            baz.doTheThing()
        }
    }

    لراحتك، يمكنك كتابة الدالة التي تخلق كائن المفوض:

    fun <T> observing(initialValue: T,
                      willSet: () -> Unit = { },
                      didSet: () -> Unit = { }
    ) = object : ObservableProperty<T>(initialValue) {
        override fun beforeChange(property: KProperty<*>, oldValue: T, newValue: T): Boolean =
                true.apply { willSet() }
    
        override fun afterChange(property: KProperty<*>, oldValue: T, newValue: T) = didSet()
     }

    ثم يمكنك مجرد تمرير لامبداس إلى أنها willSet و didSet ( الوسيطة الافتراضية بالنسبة لهم هو { } ). الاستعمال:

    var foo: String by observing("bar", willSet = {
        baz.prepareToDoTheThing()
    }, didSet = {
        baz.doTheThing()
    })
    
    var baq: String by observing("bar", didSet = { println(baq) })

على أي حال، والامر متروك لكم للتأكد من أن التعليمات البرمجية مراقبة التغييرات لا تعيين الخاصية مرة أخرى لأنه من المرجح أن تقع في العودية لانهائية، وإلا يمكنك التحقق من ذلك في رمز الرصد ما إذا كان يدعى واضعة بشكل متكرر.

أنا أحب هذا بناء سويفت. انها مفيدة جدا لكثير من الأشياء:

var foo: Bar = Bar() {
    willSet {
        baz.prepareToDoTheThing()
    }
    didSet {
        baz.doTheThing()
    }
}

وأنا أحب أن تفعل هذا في كوتلين. ومع ذلك، لا أستطيع أن أجد بناء الجملة الصحيح !

هل هناك أي شيء في كوتلين مثل هذا؟

var foo: Bar = Bar()
    willSet() {
        baz.prepareToDoTheThing()
    }
    didSet() {
        baz.doTheThing()
    }




didset