Доступ к месторождению Котлин без запуска его добытчика - PullRequest
2 голосов
/ 15 октября 2019

У меня есть класс, который содержит MutableList, и класс вносит изменения в этот список. Я определил метод получения, чтобы внешние модули могли получить копию списка. Проблема в том, что всякий раз, когда я получаю доступ к полю внутри класса, я в конечном итоге изменяю копию списка, а не фактический список. Как я могу получить доступ к списку, не проходя через геттер внутри определенного класса? Считается ли это плохой практикой, если да, то почему?

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)
    }
}

Ответы [ 4 ]

1 голос
/ 15 октября 2019

Похоже, что нет никакого соглашения для доступа к автоматически созданному полю поддержки. Документы Kotlin о полях поддержки объявляют явное свойство поддержки:

private val _clients = mutableListOf<SocketChannel>()
val clients: MutableList<SocketChannel>
        get() = _clients.toMutableList()

Примечание: я не фанат этого синтаксиса, поскольку он обязывает вас помнить, какие поля выподвергается (доступ к ним через _ префиксные имена). Я бы, вероятно, использовал clientsInternal, поэтому моя IDE может порекомендовать его, и я могу выбрать без возврата, чтобы добавить _.

1 голос
/ 15 октября 2019

Если ваш доступ однопоточный, я думаю, что вы могли бы избежать создания копий, выполнив это:

private val clientsList = mutableListOf<SocketChannel>()

val clients: List<out SocketChannel>
    get() = clientsList as List<out SocketChannel>
1 голос
/ 15 октября 2019

Проблема в этой строке: get() = field.toMutableList()

Посмотрите на определение toMutableList: он создает новую коллекцию. Просто верните field или вообще не указывайте получатель.

0 голосов
/ 15 октября 2019
@JvmField
val clients = mutableListOf<SocketChannel>()

fun getClients() = clients.toMutableList()
...