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



каков эквивалент этого выражения в Котлине?



a ? b : c


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

2904   26  

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

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

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

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

лично для меня код выше более читабельный чем if строительство подстановкой

В Котлин, 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

здесь нет тернарного оператора в Котлине, как то 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
}

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

посмотри docs:

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

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

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

b.takeIf { a } ?: c

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

b.takeIf { a }

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

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

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

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

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

 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 {} с оператором Элвиса:

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
}

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

в Kotlin, если это выражение, т. е. оно возвращает значение.

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

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

var a = if (a) b else c

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

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

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

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

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

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

при работе с apply (), let кажется очень удобным при работе с троичными операциями, так как это более элегантно и дает вам пространство

val columns: List<String> = ...
val band = Band().apply {
    name = columns[0]
    album = columns[1]
    year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}

Comments

    Ничего не найдено.