kotlin-學習-語法3-Built-in delegates - Kotlin Vocabulary 詞彙 文章 視頻

詞彙

by :關鍵字 指定類委託 、屬性委託
lazy():是一個函數, 接受一個 Lambda 表達式作爲參數, 返回一個 Lazy 實例的函數,返回的實例可以作爲實現延遲屬性的委託: 第一次調用 get() 會執行已傳遞給 lazy() 的 lamda 表達式並記錄結果, 後續調用 get() 只是返回記錄的結果。
Delegates.observable(): 函數接受兩個參數: 第一個是初始化值, 第二個是屬性值變化事件的響應器(handler);在屬性賦值後會執行事件的響應器(handler),它有三個參數:被賦值的屬性、舊值和新值
notNull: 適用於那些無法在初始化階段就確定屬性值的場合。需要注意,如果屬性在賦值前就被訪問的話則會拋出異常
Delegates.vetoable(): 變量值更新前的攔截,可以控制是否接收改變

文章

kotlin語法-委託屬性

簡單教程-kotlin 委託 ( delegate )

視頻

android Developer訂閱號-Built-in delegates - Kotlin Vocabulary

android Developer訂閱號-Delegating delegates - Kotlin Vocabulary


Delegates help you delegate tasks to other objects and provide better coder use,which you can learn more in this video.
Kotlin not only supports an easier way to implement delegates with by[關鍵字 ] keyword, but also providers built-in delegates such as lazy,observable ,vetoable,and not null in the kotlin standard library.

Let's see these built-in delegates and how they work under the hood. But,before that ,I bet you'll like this video and want to subcribe to the channel. Don't you .


    lazy()

The lazy function is a property delegate that helps you to lazily initialize properties.

That's when they are first accessed .Lazy can be really helpful for objects which are expensive to create.

Lazy takes two parameters ,a LazyThreadSafetyMode enum value and a lambda.
The lazyThreadSafetyMode parameter specifies how the initialization is synchronized between different threads. Lazy uses a default value of LazyThreadSafety Mode.SYNCHRONIZED,which means the initialization is thread safe at the cost of a slight performance impact from explicit synchronization.

    lazy(){
        // initializer
    }

The lambda is executed when the property is accessed for the first time. And its value is stored for future access.

When checking the decompiled Jave code, we seee that the Kotlin comipler creates a reference of object type lazy for the lazy delegate.

Let's take a took at the source code of lazy function. Since the lazy function uses LazyThreadSafetyMode synchronized by default,it returns a lazy object of type synchronized lazy input class.

When teh delegated property is first accessed the getvalue function of SynchronizedLazyImpl is called ,which initializes the property in a synchronized block.
This guarantees that the lazy object is initialized in a thread safe manner ,but it's the performance cost of the synchronized block.

If you are sure that this resource will be initialized by a single thread ,you can pass LazyThreadSafeMode.NONE to lazy and the function will not use the synchronized block during initialzation.

However,keep in mind that LazyThreadSafetyMode.NONE doesn't change the synchronous nature of lazy initialization. Lazy initialization still takes the same amount of time as non-lazy initialization of the object on the first access.

This means objects which take long to initialize can still block the UI thread if accessed from it . Lazy initialization can be helpful to initialize expansive resources.

However ,for simple objects ,such as a string lazy adds overhead by generating other objects, such as lazy and KProperty.

    Delegates.observable()

observable is another built-in delegate of the Kotlin standard library.

Observer is a design pattern in which an object maintians a list of its dependents called observers and notifies them automatically when its state changes.

This pattern can be really helpful when more than one object needs to be informed wehn a value has changed,rather than having each dependent object periodically call and check if the resource is updated.

Observable takes two parameters--the initial value and the listener handler that will be called when the value is modified. Observable creates an observable property object that executes the lambda you pass to the delegate each time the setter is called.

Looking ta the decompiled person class, we see that the kotlin compiler generates a class that extends the observable property. This class also implements a function called afterChange that has the lambda function ,which is passed to the observable delegate.

The afterChange function is envoked by the setter of the parent observable property class. This means each time a caller sets a new value for address, the setter will automatically mark the afterChange function,resulting in all the listeners to be nofitied about the change.

You can also see a call to beforeChange in the decompiled code. beforeChange is not used by the observable delegate, but is used by the delegate which is coming up next. Vetoable

Delegates.vetoable()

Vetoable is another build-in delegate in which the property delegates veto rights to its value. Similar to the observable delegate, vetoable takes two parameters--the initial value and the listener handler that will be called wehn any caller wants to modify the value of the property.

If the lambda function returns true, the property value will be modified. Else ,the value will stay the same. In this case, if the caller tries to update the address with anything smaller than 15 characters, the current value will be preserved.

Looking at the decompiled person class, Kotlin generates a new class ,which extends to observable property . The generated class includes the lambda we passed in beforeChange function,which will be called by the setter before the values is set.

    Delegates.notNull()

The last built-in delegate I'll talk about is Delegates.notNull. notNull simply allows the property to be initialized at a later time.

notNull is similar to lateinit. In most cases,lateinit is preferred, since notNull creates an extra object for each property. However,you can use notNull with primitive types, which lateinit doesn't support.

which lateinit doesn't support. notNull uses a special type of read-write property named notNull var.

Looking at the decompiled code ,the full name property is initialized with the notNull function,which returns a notNull var object.

The notNull var class simply holds a generic nullable internal reference and throws illegal state exception if any call calls the getter before the value is initialized.

The kotlin standard library provides a set of built-in delegates so you don't need to write ,maintain, and reinvent them.
Built-in delegates initialize fields lazily,allow primitive types to be initialized later, observe and get notified when a value changes , and even veto those changes.


Thanks for watching.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章