Что эквивалентно этому выражению в Котлине?
a ? b : c
Это неверный код в Котлине.
Что эквивалентно этому выражению в Котлине?
a ? b : c
Это неверный код в Котлине.
В Kotlin, if
утверждения являются выражениями. Таким образом, следующий код эквивалентен:
if (a) b else c
Здесь важно различие между выражением и высказыванием. В Java/С#/JavaScript, if
формирует оператор, то есть он не разрешает значение. Более конкретно, вы не можете назначить его переменной.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Если вы исходите с языка, где, if
это утверждение, это может показаться неестественным, но это чувство должно скоро исчезнуть.
Вы можете определить свою собственную функцию расширения Boolean
которая возвращает null
когда Boolean
false
является false
чтобы создать структуру, похожую на тернарный оператор:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Это сделает a? b: c
a? b: c
выражение a? b: c
преобразуется в a then b?: c
, как показано ниже:
println(condition then "yes" ?: "no")
Обновление. Но для того, чтобы сделать еще один условный переключатель, похожий на Java, вам понадобится нечто подобное
infix fun <T> Boolean.then(param:() → T): T? = if (this) param() else null
println(condition then { "yes" }?: "no")
обратите внимание на лямбда. его расчет содержания должен быть отложен до тех пор, пока мы не убедимся в том, что condition
true
Этот выглядит неуклюжим, поэтому существует высокий спрос на порт Java-оператора Tortary в Котлин
if (a) b else c
- это то, что вы можете использовать вместо выражения Java a? b: c
a? b: c
.
В Kotlin многие операторы управления, в том числе if
, when
или даже try
могут использоваться как выражения. Это означает, что у них может быть результат, который можно присвоить переменной, вернуть из функции и т.д.
В результате Котлину не нужен троичный оператор.
if (a) b else c
- это то, что вы можете использовать вместо выражения Java a? b: c
a? b: c
.
Я думаю, что идея в том, что последний менее читабелен, так как все знают, что делает ifelse
, тогда как ? :
? :
довольно неудобно, если вы уже не знакомы с синтаксисом. Хотя должен признать, что мне часто не хватает более удобного троичного оператора.
Другие альтернативы
когда
Вы также можете многое увидеть when
построении всякий раз, когда условия проверяются в Kotlin. Это также способ выразить каскад if-else альтернативным способом. Следующее соответствует вашему примеру.
when(a) {
true -> b
false -> c
}
расширения
Как показывают многие хорошие примеры (Kotlin Ternary Conditional Operator) в других ответах, расширения также могут быть подходящим вариантом.
Для себя я использую следующие функции расширения:
fun T?.or<T>(default: T): T = if (this == null) default else this
fun T?.or<T>(compute: () -> T): T = if (this == null) compute() else this
Сначала будет возвращено предоставленное значение по умолчанию, если объект равен нулю. Второй будет оценивать выражение, представленное в лямбда в том же случае.
Использование:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Лично для меня код выше более читаемого, чем if
встроенная конструкция
В kotlin нет тернарного оператора, поскольку блок if else
возвращает значение
так что вы можете сделать: val max = if (a > b) a else b
вместо java max = (a > b)? b: c
max = (a > b)? b: c
Мы также можем использовать when
построении, это также возвращает значение:
val max = when(a > b) {
true -> a
false -> b
}
Вот ссылка на документацию kotlin: Control Flow: if, when, for, while
В Kotlin
if
- это выражение, то есть оно возвращает значение. Следовательно нет тройного оператора(condition ? then : else)
, потому что обычный, если работает отлично в этой роли. ручной источник отсюда
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
Некоторые угловые случаи, не упомянутые в других ответах.
С появлением takeIf в Kotlin 1.1 тройной оператор a ? b : c
также может быть выражен следующим образом:
b.takeIf { a } ?: c
Это становится еще короче, если c null
:
b.takeIf { a }
Также обратите внимание, что типичный в Java-мире нуль проверяет, как value != null ? value : defaultValue
переводит в идеоматическом Kotlin только value ?: defaultValue
.
Аналогичный a != null ? b : c
можно перевести на a?.let { b } ?: c
.
Взгляните на документы:
В Kotlin, if является выражением, т.е. оно возвращает значение. Поэтому нет тройного оператора (условие? Then: else), потому что обычный, если работает отлично в этой роли.
Java
int temp = a ? b : c;
Эквивалентен Котлину:
var temp = if (a) b else c
при замене оператора switch C-подобных языков. В простейшей форме это выглядит как
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
Java-эквивалент троичного оператора
a ? b : c
- это простой IF в Котлине в одну строку
if(a) b else c
нет тернарного оператора (условие? тогда: еще), потому что обычный, если отлично работает в этой роли.
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Особый случай для нулевого сравнения
Вы можете использовать оператор Элвиса
if ( a != null ) a else b
// equivalent to
a ?: b
В Котлине нет тройного оператора. Это кажется проблематичным с первого взгляда. Но подумайте, что мы можем сделать это с помощью inline if else, потому что это выражение здесь. Просто мы должны сделать -
var number = if(n>0) "Positive" else "Negetive"
Здесь мы можем еще, если блок слишком много, сколько нам нужно. Как -
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Итак, эта строка настолько проста и понятна, как трехмерный оператор. когда мы используем более одного тернарного оператора в java, это кажется ужасным. Но здесь мы имеем четкий синтаксис. даже мы можем написать его также в нескольких строках.
Вы можете использовать var a= if (a) b else c
вместо тернарного оператора.
Еще одна хорошая концепция котлина - оперативник Элвиса. Вам не нужно проверять значение null каждый раз.
val l = b?.length ?: -1
Это вернет длину, если b не является нулевым, иначе выполняется оператор правой стороны.
как цитируется Дрю Ноукс, kotlin использует выражение if как выражение, поэтому Тернарный Условный Оператор больше не нужен,
но с функцией расширения и перегрузкой infix вы можете реализовать это самостоятельно, вот пример
infix fun <T> Boolean.then(value: T?) = TernaryExpression(this, value)
class TernaryExpression<out T>(val flag: Boolean, val truly: T?) {
infix fun <T> or(falsy: T?) = if (flag) truly else falsy
}
тогда используйте его так:
val grade = 90
val clazz = (grade > 80) then "A" or "B"
Вы можете сделать это много в Kotlin
Использование if
if(a) b else c
Использование, когда
when (a) {
true -> print("value b")
false -> print("value c")
else -> {
print("default return in any other case")
}
}
Нулевая безопасность
val a = b ?: c
ЗАДАЧА:
Давайте рассмотрим следующий пример:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Нам нужен следующий эквивалент в Kotlin:
вернуть (! answer.isSuccessful())
?
"неправильно":
answer.body(). string()
РЕШЕНИЯ:
1.a. Вы можете использовать if-expression
в Kotlin:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.б. Может быть намного лучше, если вы перевернете это if-expression
(пусть делают это без not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 Оператор Котлинс Элвис ?:
Может сделать работу еще лучше
return answer.body()?.string() ?: "wrong"
3 Или используйте функцию Extension function
для соответствующего класса Answer
:
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
4 Используя Extension function
вы можете уменьшить код благодаря Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
5 Или просто используйте when
оператор:
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
Надеюсь это поможет.
Еще один интересный подход - использовать when
:
when(a) {
true -> b
false -> b
}
Может оказаться весьма полезным в некоторых более сложных сценариях. И, честно говоря, это более читаемо для меня, чем if ... else ...
В Котлине нет тройной операции, но есть некоторые интересные способы обойти это. Как указывали другие, прямой перевод в Котлин будет выглядеть так:
val x = if (condition) result1 else result2
Но, лично, я думаю, что это может стать немного загроможденным и трудночитаемым. В библиотеку встроены некоторые другие функции. Вы можете использовать takeIf {} с оператором elvis:
val x = result1.takeIf { condition } ?: result2
Что происходит в том, что команда takeIf {} возвращает либо ваш результат1, либо нуль, а оператор elvis обрабатывает нулевой вариант. Существуют некоторые дополнительные опции takeUnless {}, например:
val x = result1.takeUnless { condition } ?: result2
Язык понятен, вы знаете, что это делает.
Если это обычно используется, вы также можете сделать что-то веселое, как использовать встроенный метод расширения. Предположим, что мы хотим отслеживать оценку игры как Int, например, и мы хотим всегда возвращать 0, если данное условие не выполняется:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Хорошо, это кажется уродливым. Но подумайте, как он выглядит, когда он используется:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Как вы можете видеть, Kotlin предлагает большую гибкость в том, как вы решите выразить свой код. Есть бесчисленные вариации моих примеров и, вероятно, способы, которых я еще не обнаружил. Надеюсь, это поможет!
в Котлине нет тройного оператора, ибо существует выражение:
var d = if (a) b else c
Помните, что тернарный оператор и оператор Элвиса имеют разные значения в котлинском языке, в отличие от многих популярных языков. Делать expression? value1: value2
expression? value1: value2
даст вам плохие слова компилятором Kotlin, в отличие от любого другого языка, так как в Kotlin нет трехзначного оператора, как упомянуто в официальных документах. Причина в том, что операторы if, when и try-catch сами возвращают значения.
Так что, делать expression? value1: value2
expression? value1: value2
можно заменить на
val max = if (a> b) print ("Выбрать a") else print ("Выбрать b")
Оператор Элвиса, который есть у Котлина, работает только в случае обнуляемых переменных, напр.:
Если я сделаю что-то вроде
value3 = value1?: value2
тогда, если value1 равно нулю, будет возвращено значение2, в противном случае будет возвращено значение1.
Из этих ответов можно достичь более четкого понимания.
Вы можете использовать, if
выражение для этого в Котлин. В Kotlin if
- выражение с результатом результата. Итак, в Котлине мы можем написать
fun max(a: Int, b: Int) = if (a > b) a else b
и в Java мы можем добиться того же, но с большим кодом
int max(int a, int b) {
return a > b ? a : b
}
Еще один короткий подход к использованию
val value : String = "Kotlin"
value ?: ""
Здесь kotlin сам проверяет значение null, а если оно равно null, то он передает пустое строковое значение.
В Котлине нет тройного оператора.
В Kotlin, if является выражением, т.е. оно возвращает значение.
Поэтому нет тройного оператора (условие? Then: else), потому что обычный, если работает отлично в этой роли.
Эквивалент в Котлине
var a = if (a) b else c
Справочный документ: Контрольный поток: если, когда, для, пока
Зачем использовать что-то вроде этого:
when(a) {
true -> b
false -> b
}
когда вы действительно можете использовать что-то вроде этого (a
в этом случае является логическим):
when {
a -> b
else -> b
}
Если вам не нужно использовать стандартную нотацию, вы также можете создать/смоделировать ее, используя infix, примерно так:
создайте класс для хранения вашей цели и результата:
data class Ternary<T>(val target: T, val result: Boolean)
создать некоторые инфиксные функции для симуляции троичной операции
infix fun <T> Boolean.then(target: T): Ternary<T> {
return Ternary(target, this)
}
infix fun <T> Ternary<T>.or(target: T): T {
return if (this.result) this.target else target
}
Тогда вы сможете использовать его так:
val collection: List<Int> = mutableListOf(1, 2, 3, 4)
var exampleOne = collection.isEmpty() then "yes" or "no"
var exampleTwo = (collection.isNotEmpty() && collection.contains(2)) then "yes" or "no"
var exampleThree = collection.contains(1) then "yes" or "no"
Со следующими функциями infix я могу охватывать многие распространенные случаи использования почти так же, как это можно сделать в Python:
class TestKotlinTernaryConditionalOperator {
@Test
fun testAndOrInfixFunctions() {
Assertions.assertThat(true and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(false and "yes" or "no").isEqualTo("no")
Assertions.assertThat("A" and "yes" or "no").isEqualTo("yes")
Assertions.assertThat("" and "yes" or "no").isEqualTo("no")
Assertions.assertThat(1 and "yes" or "no").isEqualTo("yes")
Assertions.assertThat(0 and "yes" or "no").isEqualTo("no")
Assertions.assertThat(Date() and "yes" or "no").isEqualTo("yes")
@Suppress("CAST_NEVER_SUCCEEDS")
Assertions.assertThat(null as Date? and "yes" or "no").isEqualTo("no")
}
}
infix fun <E> Boolean?.and(other: E?): E? = if (this == true) other else null
infix fun <E> CharSequence?.and(other: E?): E? = if (!(this ?: "").isEmpty()) other else null
infix fun <E> Number?.and(other: E?): E? = if (this?.toInt() ?: 0 != 0) other else null
infix fun <E> Any?.and(other: E?): E? = if (this != null) other else null
infix fun <E> E?.or(other: E?): E? = this ?: other
При работе с apply(), пусть кажется очень удобным при работе с тройными операциями, поскольку он более изящный и дает вам комнату
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
используйте условное выражение if-else или оператор следующим образом
when(a) {
true -> b
false -> b
}
В Котлине нет тройного оператора, наиболее закрытыми являются следующие два случая:
val a = true if(a) print("A is true") else print("A is false")
Если выражение слева от?: Не является нулевым, оператор elvis возвращает его, иначе он возвращает выражение вправо. Заметим, что выражение правой части оценивается только в том случае, если левая часть равна нулю.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
Пример: var energy: Int = data?.get(position)?. energy?.toInt()?: 0
В kotlin, если вы используете ?: Он будет работать, как если бы оператор вернул null тогда ?: 0 это займет 0 или что бы вы ни писали на этой стороне.