我想知道科特林的'= lazy'与'by lazy'有什么区别
val host by lazy { ... }
val host = lazy { ... }
在我的Android代码中
val host by lazy {
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
}
成功
但此代码
val host = lazy {
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
}
失败了
答案 0 :(得分:0)
lazy { ... }
部分指定一个返回Lazy<T>
的函数。
如果您只说val foo = lazy { "bar" }
,那么任何get或set操作都将在Lazy<String>
实例上进行。
使用val foo by lazy { "bar" }
时,是在告诉编译器将foo
上的所有get或set操作委托给String
。
如果我们有这个:
class Test {
val usingAssign = lazy {
"bar"
}
val usingBy by lazy {
"bar"
}
}
,我们看一下相应的Java代码,它看起来像这样:
private final Lazy usingAssign;
private final Lazy usingBy$delegate;
public final Lazy getUsingAssign() {
return this.usingAssign;
}
public final String getUsingBy() {
Lazy var1 = this.usingBy$delegate;
KProperty var3 = $$delegatedProperties[0];
return (String)var1.getValue();
}
public Test() {
this.usingAssign = LazyKt.lazy((Function0)null.INSTANCE);
this.usingBy$delegate = LazyKt.lazy((Function0)null.INSTANCE);
}
因此,任何尝试读取usingBy
的尝试都会给我们String
,然后我们可以例如分配给另一个String
变量。您无法使用usingAssign
来执行此操作,因为其类型为Lazy<String>
。
答案 1 :(得分:0)
by lazy
表示,该逻辑将在首次使用时执行
惰性属性:仅在首次访问时才计算该值
使用时
val host = lazy {
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
}
您基本上将惰性属性分配给主机变量。这样就变成了Lazy<Something>
,您可以从中获取值或检查其是否已初始化。
by lazy {"test"}
->给出String
= lazy { "test" }
->给出Lazy<String>
答案 2 :(得分:0)
val host by lazy { ... }
这意味着主机属性是Kotlin's lazy delegate增强的属性。首次访问时,其值仅计算一次。后续通话仅返回第一次通话的缓存结果。
val host = lazy { ... }
另一方面,这意味着不包含通过委托增强的主机属性,它包含一个惰性委托。由于它包含委托对象,因此您可以访问其方法,例如isInitialized()或访问将触发其计算的委托的value。
考虑以下示例:
val host = lazy {
println("computed!")
"Hello"
}
fun main() {
println(host)
println(host.value)
println(host)
}
在这里,我们有一个懒惰的代表host
。如果尝试打印其值,则会得到:“惰性值尚未初始化。” 。但是,一旦访问它的值,其行为便与by lazy {...}