在没有 运行 的情况下访问 Kotlin 字段是 getter
Accessing Kotlin field without running it's getter
我有一个包含 MutableList 的 class,class 对该列表进行更改。我定义了一个 getter 以允许外部模块获取列表的副本。问题是每当我访问 class 中的字段时,我最终都会更改列表副本而不是实际列表。如何在不通过定义的 class 内的 getter 的情况下访问列表?这是否被认为是不好的做法,如果是,为什么?
class Server(private val port: Int): Runnable {
val clients = mutableListOf<SocketChannel>()
get() = field.toMutableList()
private val sel = Selector.open()
private val serverChannel = NIOServerChannel(port, sel).get()
private val engine = ServerEngine(sel, clients)
private val acceptor = ChannelAcceptor(serverChannel, clients)
private val reader = ChannelReader()
private val writer = ChannelWriter()
private val middleware = Middleware()
override fun run() {
buildEngine()
println("Starting server on port: $port")
engine.run()
}
fun use(func: (String, Response) -> Unit) = middleware.add(BiConsumer(func))
private fun buildEngine() {
reader.process = middleware.get()
engine.add(acceptor)
engine.add(reader)
engine.add(writer)
}
}
问题出在这一行:get() = field.toMutableList()
查看 definition of toMutableList
:它创建了一个新集合。只需 return field
或完全省略 getter。
似乎没有任何访问自动创建的支持字段的约定。 Kotlin docs on backing fields 声明一个显式支持 属性:
private val _clients = mutableListOf<SocketChannel>()
val clients: MutableList<SocketChannel>
get() = _clients.toMutableList()
注意:我不喜欢这种语法,因为它要求您记住公开了哪些字段(通过 _ 前缀名称访问它们)。我可能会使用 clientsInternal
,所以我的 IDE 可以推荐它,我可以 select 而无需回溯添加 _.
如果您的访问是单线程的,我认为您可以通过这样做来避免创建副本:
private val clientsList = mutableListOf<SocketChannel>()
val clients: List<out SocketChannel>
get() = clientsList as List<out SocketChannel>
@JvmField
val clients = mutableListOf<SocketChannel>()
fun getClients() = clients.toMutableList()
我有一个包含 MutableList 的 class,class 对该列表进行更改。我定义了一个 getter 以允许外部模块获取列表的副本。问题是每当我访问 class 中的字段时,我最终都会更改列表副本而不是实际列表。如何在不通过定义的 class 内的 getter 的情况下访问列表?这是否被认为是不好的做法,如果是,为什么?
class Server(private val port: Int): Runnable {
val clients = mutableListOf<SocketChannel>()
get() = field.toMutableList()
private val sel = Selector.open()
private val serverChannel = NIOServerChannel(port, sel).get()
private val engine = ServerEngine(sel, clients)
private val acceptor = ChannelAcceptor(serverChannel, clients)
private val reader = ChannelReader()
private val writer = ChannelWriter()
private val middleware = Middleware()
override fun run() {
buildEngine()
println("Starting server on port: $port")
engine.run()
}
fun use(func: (String, Response) -> Unit) = middleware.add(BiConsumer(func))
private fun buildEngine() {
reader.process = middleware.get()
engine.add(acceptor)
engine.add(reader)
engine.add(writer)
}
}
问题出在这一行:get() = field.toMutableList()
查看 definition of toMutableList
:它创建了一个新集合。只需 return field
或完全省略 getter。
似乎没有任何访问自动创建的支持字段的约定。 Kotlin docs on backing fields 声明一个显式支持 属性:
private val _clients = mutableListOf<SocketChannel>()
val clients: MutableList<SocketChannel>
get() = _clients.toMutableList()
注意:我不喜欢这种语法,因为它要求您记住公开了哪些字段(通过 _ 前缀名称访问它们)。我可能会使用 clientsInternal
,所以我的 IDE 可以推荐它,我可以 select 而无需回溯添加 _.
如果您的访问是单线程的,我认为您可以通过这样做来避免创建副本:
private val clientsList = mutableListOf<SocketChannel>()
val clients: List<out SocketChannel>
get() = clientsList as List<out SocketChannel>
@JvmField
val clients = mutableListOf<SocketChannel>()
fun getClients() = clients.toMutableList()