Троичный Условный Оператор Котлина

что эквивалентно этому выражению в Котлине?

a ? b : c

это недопустимый код в Kotlin.

26 ответов


В Котлин, if выражения. Таким образом, следующий код эквивалентен:

if (a) b else c

здесь важно различие между выражением и утверждением. В Java / C# / JavaScript,if формирует оператор, что означает, что он не разрешает значение. Более конкретно, вы не можете назначить его переменной.

// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c

если вы исходите из языка, где if это заявление, это может показаться неестественным, но это чувство скоро спадать.


вы можете определить свой собственный Boolean функция расширения, которая возвращает null когда Boolean и false чтобы обеспечить структуру, аналогичную тернарному оператору:

infix fun <T> Boolean.then(param: T): T? = if (this) param else null

это 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 ternary operator в Kotlin


для себя я использую следующие функции расширения:

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

First one вернет значение по умолчанию, если object равен null. Второй будет оценивать выражение в лямбда в этом случае.

использование:

1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }

лично для меня код выше более читаемый, чем if конструкция inlining


В Котлин, if является выражением, т. е. возвращает значение. Следовательно нет троичного оператора (condition ? then : else), потому что обычный if отлично работает в этой роли. ручной источник отсюда

// 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

здесь нет тернарный оператор в Котлине, как то if else блок возвращает значение

Итак, вы можете сделать: val max = if (a > b) a else b вместо java max = (a > b) ? b : c

мы также можем использовать when конструкция, она также возвращает значение:

val max = when(a > b) {
    true -> a
    false -> b
}

вот ссылка для документации Котлина:поток управления: если, когда, для, пока


посмотри docs:

в Kotlin, if-это выражение, т. е. оно возвращает значение. Поэтому нет ли троичного оператора (условия ? потом : еще), потому что обычный if отлично работает в этой роли.


некоторые случаи, не указанные в других ответах.

С момента появления takeIf на Котлин 1.1 тернарный оператор a ? b : c также может быть выражено так:

b.takeIf { a } ?: c

это становится еще короче, если c null:

b.takeIf { a }

также обратите внимание, что типичный в Java world null проверяет, как value != null ? value : defaultValue перевести в ideomatic Котлин просто value ?: defaultValue.

как a != null ? b : c можно перевести на a?.let { b } ?: c.


Котлин имеет выражения

в Котлине многие операторы управления, включая if, when или даже try может использоваться как выражения. Это означает, что они имеют результат и могут быть назначены переменной, возвращенной из функции и т. д.

синтаксически, нет необходимости в троичном операторе

сказав, что Котлину не нужен тернарный оператор.

if (a) b else c что можно использовать вместо Ява выражение a ? b : c.

Я думаю, идея в том, что последнее менее читаемо, так как все знают, что ifelse делает, а ? : довольно неудобно, если вы не знакомы с синтаксисом. Хотя я должен признать, что часто пропускаю более удобный тройной оператор.

Другие Альтернативы

, когда

вы также можете увидеть много when конструкции всякий раз, когда условия проверяются в Котлине. Это также способ express if-else каскадирует альтернативным способом. Вашему примеру соответствует следующее.

when(a) {
    true -> b
    false -> c
}

расширения

как много хороших примеров (Котлин Троичный Условный Оператор) в других ответах показывают, расширения также могут быть способом пойти.


Java

int temp = a ? b : c;

эквивалент Котлина:

var temp = if (a) b else c

когда заменяет оператор коммутатора C-подобных языков. В простейшей форме это выглядит так

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}

в Котлине нет троичного оператора. На первый взгляд это кажется проблематичным. Но думаю, мы можем сделать это с помощью 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, это кажется ужасным. Но здесь мы имеем ясный синтаксис. даже мы можем написать это в нескольких строках тоже.


как Дрю Ноукс цитирует, Котлин использовать, если заявление, как выражение, поэтому тернарный условный оператор больше не нужен,

но с функцией расширения и перегрузкой 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"

другим интересным подходом было бы использовать when:

when(a) {
  true -> b
  false -> b
}

может быть очень удобно в некоторых более сложных сценариях. И, честно говоря, это более читаемо для меня, чем if ... else ...


вы можете сделать это много способов в Котлине

  1. использование if

    if(a) b else c
    
  2. использование when

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
    
  3. Нулевое Безопасность

    val a = b ?: c
    

в Котлине нет троичного оператора, для этого есть выражение if:

var d = if (a) b else c

согласно документации Котлина для себя, я использую следующий код:

 val max = if (a > b) a else b

и:

when (x) {
  1 -> print("x == 1")
  2 -> print("x == 2")
  else -> { // Note the block
      print("x is neither 1 nor 2")
  }
}

Если вы хотите знать больше информации, проверьте эту ссылку : поток управления: если, когда, Для, в то время как


можно использовать if выражение для этого в Котлин. В Котлине 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 x = if (condition) result1 else result2

но лично я думаю, что это может быть немного загромождено и трудно читать. В библиотеку встроены и другие опции. Вы можете использовать takeIf {} с оператором elvis:

val x = result1.takeIf { condition } ?: result2

происходит то, что команда takeIf { } возвращает либо ваш result1, либо null, и оператор elvis обрабатывает параметр null. Есть несколько дополнительных опций, 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 предлагает большую гибкость в том, как вы решаете выразить свой код. Есть бесчисленные вариации моих примеров и, вероятно, способов, которые я еще даже не обнаружил. Надеюсь, это поможет!


еще один короткий подход к использованию

val value : String = "Kotlin"

value ?: ""

здесь Котлин сам проверяет значение null, и если оно равно null, то оно передает пустое строковое значение.


зачем использовать что-то вроде этого:

when(a) {
  true -> b
  false -> b
}

когда вы действительно можете использовать что-то вроде этого (a является логическим в этом случае):

when {
  a -> b
  else -> b
}

в Котлине есть нет тернарный оператор.

в Котлине if-это выражение, т. е. оно возвращает значение.

поэтому нет троичного оператора (условие ? потом : еще), потому что обычный if отлично работает в этой роли.

эквивалент в Котлин

var a = if (a) b else c

ссылка на документ: поток управления: если, когда, для, пока


со следующими функциями 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

используйте условный оператор if-else или оператор when следующим образом

when(a) {
  true -> b
  false -> b
}

в Котлине нет троичного оператора, наиболее закрытыми являются следующие два случая,

  • если еще как выражение

val a = true if(a) print("A is true") else print("A is false")

  • оператор Элвис

Если выражение слева от ?: не равно null, оператор elvis возвращает его, в противном случае он возвращает выражение вправо. Отмечать что правая часть выражения вычисляется только если левое сторона имеет значение null.

 val name = node.getName() ?: throw IllegalArgumentException("name expected")

справочные документы


пример: var энергия: Int = данные?.получить (позицию)?.энергии?.toInt() ?: 0

в Котлине, если вы используете ?: это будет работать, как если бы оператор вернул null тогда ?: 0 это займет 0 или все, что у вас есть, напишите эту сторону.


при работе с 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
}