Обращение к методу Nullable переменной в Kotlin

165
20 мая 2018, 02:40

Пытаюсь перевести следующий код из java в kotlin:

private LGMThread lgmThread;
if (!lgmThread.isThreadStarted()) {
    lgmThread.start();
} else {
    lgmThread.openChannel();
}

Вместе с автоматическим конвертером кода Android Studio я перевела это в:

private var lgmThread: LGMThread? = null
if (!lgmThread.isThreadStarted()) {
        lgmThread?.start()
} else {
        lgmThread?.openChannel()
}

однако при этом AS ругается на выражение !lgmThread.isThreadStarted():

Я пробовала исправить это следующим образом:

lgmThread?.let {
    if (!lgmThread.isThreadStarted()) {
        lgmThread?.start()
    } else {
        lgmThread?.openChannel()
    }
}

однако это не решает проблему:

И код

if (lgmThread != null) { 
    if (!lgmThread.isThreadStarted()) {
        lgmThread?.start()
    } else {
        lgmThread?.openChannel()
    }
}

приводит к точно такому же результату.

Код

if (!lgmThread?.isThreadStarted()) {
            lgmThread?.start()
} else {
            lgmThread?.openChannel()
}

также приводит к другой ошибке:

С оператором !!, конечно, ошибка исчезает:

if (!lgmThread!!.isThreadStarted()) {
     lgmThread?.start()
} else {
     lgmThread?.openChannel()
}

однако я не хочу использовать этот способ. Как правильно избавиться от этой ошибки, не прибегая к оператору !!?

Answer 1

Так как lgmThread имеет тип LGMThread?, то и возвращаемое методом lgmThread?.isThreadStarted() значение будет иметь тип Boolean?

В таком случае в блоке if вы можете проверять lgmThread?.isThreadStarted() на true, false и null

Соответственно, кусок кода может выглядеть следующим образом:

private var lgmThread: LGMThread? = null
if (lgmThread?.isThreadStarted() == false) {
   lgmThread?.start()
} else {
   lgmThread?.openChannel()
}

P.S. Но будьте внимательны, так как в таком случае код в блоке else выполнится при lgmThread?.isThreadStarted() равном true и null

Answer 2

Ваша мысль с let была в верном направлении, только вы не изучили теорию как следует. Такое решение гораздо элегантнее.

lgmThread?.let {
    if (!it.isThreadStarted()) {
        it.start()
    } else {
        it.openChannel()
    }
}

Или run

lgmThread?.run {
    if (!isThreadStarted()) {
        start()
    } else {
        openChannel()
    }
}
READ ALSO
Не могу правильно обратиться к сервлету

Не могу правильно обратиться к сервлету

Изучаю spring mvc, сборку делаю на maven

182
Java, как использовать API?

Java, как использовать API?

Я написала API на php, основная цель которого — вытягивать данные из БД (в зависимости от GET параметров) и возвращать ихДопустим, оно находиться...

138
Циклический остаток от деления в JAVA?

Циклический остаток от деления в JAVA?

Мне нужно получить данные в диапазоне 0 до 5Если аргумент выходит за рамки то мне нужно циклически продолжить считать с другой стороны диапазона

199