所以我想实现的是,在主函数的后面一段时间设置顶层变量,但我不想让它成为一个lateinit var,这肯定会破坏掉 Extension
变量的功能。
比如这段代码就不能用,因为扩展变量不支持lateinit修饰符。
lateinit var Dispatchers.Konvironment: MainCoroutineDispatcher
private set
fun main() {
...
Dispatchers.Konvironment = ArbitraryMainDispatcher(Thread.currentThread()) { queue.add(it) }
...
}
所以我最后想出的办法是用一个虚变量来实现val变量的getter。
val Dispatchers.Konvironment: MainCoroutineDispatcher
get() = dispatcher
private lateinit var dispatcher: MainCoroutineDispatcher
fun main() {
...
dispatcher = ArbitraryMainDispatcher(Thread.currentThread()) { queue.add(it) }
...
}
但这肯定不是干净的方法。它看起来很丑陋(就是),在顶层结构中创建多个变量不是很干净的架构。
那么有什么可能的干净的变通方法吗?有点像懒惰初始化,通过一些委托人或者其他的方式。
好吧,部分回答了你的问题。
var Dispatchers.Konvironment: MainCoroutineDispatcher
get() = dispatcher
private set(value) {
dispatcher = value
}
private lateinit var dispatcher: MainCoroutineDispatcher
fun main() {
...
Dispatchers.Konvironment = ArbitraryMainDispatcher(Thread.currentThread()) { queue.add(it) }
...
}
会给你想要的赋值方式。有没有办法摆脱这个额外的 lazyinit
变量,但。
扩展不过是静态方法的一些Kotlin语法糖,这些方法以扩展类的实例作为参数之一,并执行一些操作。如果你熟悉Java,那么,比如这些扩展。
// Extensions.kt
fun Foo.extendedAction() {
println(this)
}
var Foo.extendedBar: Bar
get() = this.bar
set(value) {
this.bar = value
}
就是Java中的这些方法。
public class ExtensionsKt {
public static final void extendedAction(Foo foo) {
System.out.println(foo);
}
public static final Bar getExtendedBar(Foo foo) {
return foo.getBar();
}
public static final Bar setExtendedBar(Foo foo, Bar bar) {
foo.setBar(bar);
}
}
从上面也许可以得出的结论是,扩展类实际上并不... ... 增加 在扩展类的签名上添加任何东西,它们只是简单地 妆点 它们的附加功能。或者说,正如在 文件:
扩展实际上并不修改其扩展的类。通过定义扩展,你并没有在一个类中插入新的成员,而仅仅是使新的函数可以用点符号调用这个类型的变量。
所以你可以看到,除非 dispatcher
某种程度上已经存在于 Dispatchers
如果不提供一个外部的 "支持 "变量,你就不能做你想做的事情,这个变量的值可以被扩展实际引用。