kotlin 中的 lazy 和 lazyFast 有什么区别?

what is the difference between lazy and lazyFast in kotlin?

Kotlin lazy delegate 属性 lazy 和 lazy Fast 之间有什么区别?因为它们看起来像相同的代码。

  private val key: String by lazy {
        if (arguments != null && arguments?.getString(Constants.KEY) != null) {
            return@lazy arguments?.getString(Constants.KEY).toString()
        } else {
            return@lazy ""
        }
    }

 private val key: String by lazyFast {
        if (arguments != null && arguments?.getString(Constants.KEY) != null) {
            return@lazyFast arguments?.getString(Constants.KEY).toString()
        } else {
            return@lazyFast ""
        }
    }

懒惰:-

  • 表示延迟初始化的值。
  • 获取当前Lazy实例的延迟初始化值。初始化该值后,在此 Lazy 实例的剩余生命周期内不得更改。
  • Creates a new instance of the Lazy that uses the specified initialization function and the default thread-safety mode LazyThreadSafetyMode.SYNCHRONIZED.
  • If the initialization of a value throws an exception, it will attempt to reinitialize the value at the next access.

lazy returns 一个处理 lambda 函数(初始化器)的 Lazy 对象,根据线程执行模式(LazyThreadSafetyMode)以稍微不同的方式执行初始化。

public actual fun <T> lazy(mode: LazyThreadSafetyMode, initializer: ()
        -> T): Lazy<T> =
                when (mode) {
                    LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
                    LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
                    LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer) 
}

lazyFast:-

  • Implementation of lazy that is not thread-safe. Useful when you know what thread you will be executing on and are not worried about synchronization.

lazyFast 也是 returns 模式为 LazyThreadSafetyMode.NONE

的 Lazy 对象
fun <T> lazyFast(operation: () -> T): Lazy<T> = lazy(LazyThreadSafetyMode.NONE) {
    operation()
}

LazyThreadSafetyMode.SYNCHRONIZED:-

  • 锁用于确保只有一个线程可以初始化 Lazy 实例。

LazyThreadSafetyMode.PUBLICATION:-

  • 在并发访问未初始化的Lazy实例值时可以多次调用初始化函数,但只有第一个返回值会被用作Lazy实例的值。

LazyThreadSafetyMode.NONE :-

  • 不使用锁来同步对 Lazy 实例值的访问;如果从多个线程访问实例,则其行为未定义。除非保证 Lazy 实例永远不会从多个线程初始化,否则不应使用此模式。