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

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

a ? b : c

Это неверный код в Котлине.

+383
источник поделиться
32 ответа
  • 1
  • 2

В 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 это утверждение, это может показаться неестественным, но это чувство должно скоро исчезнуть.

+526
источник

Вы можете определить свою собственную функцию расширения 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 в Котлин

+60
источник
другие ответы

Связанные вопросы


Похожие вопросы

TL; DR

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) в других ответах, расширения также могут быть подходящим вариантом.

+41
источник

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

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 встроенная конструкция

+34
источник

В 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

+29
источник

В 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
+27
источник

Некоторые угловые случаи, не упомянутые в других ответах.

С появлением 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.

+24
источник

Взгляните на документы:

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

+23
источник

Java

int temp = a ? b : c;

Эквивалентен Котлину:

var temp = if (a) b else c
+14
источник

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

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
+12
источник

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
+12
источник

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

+10
источник

Вы можете использовать var a= if (a) b else c вместо тернарного оператора.

Еще одна хорошая концепция котлина - оперативник Элвиса. Вам не нужно проверять значение null каждый раз.

val l = b?.length ?: -1

Это вернет длину, если b не является нулевым, иначе выполняется оператор правой стороны.

+8
источник

как цитируется Дрю Ноукс, 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"
+7
источник

Вы можете сделать это много в 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
    
+7
источник

ЗАДАЧА:

Давайте рассмотрим следующий пример:

if (!answer.isSuccessful()) {
    result = "wrong"
} else {
    result = answer.body().string()
}
return result

Нам нужен следующий эквивалент в Kotlin:

вернуть (! answer.isSuccessful()) ? "неправильно" : answer.body(). string()

enter image description here

РЕШЕНИЯ:

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

Надеюсь это поможет.

+7
источник

Еще один интересный подход - использовать when:

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

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

+6
источник

В Котлине нет тройной операции, но есть некоторые интересные способы обойти это. Как указывали другие, прямой перевод в Котлин будет выглядеть так:

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

+5
источник

в Котлине нет тройного оператора, ибо существует выражение:

var d = if (a) b else c
+5
источник

Помните, что тернарный оператор и оператор Элвиса имеют разные значения в котлинском языке, в отличие от многих популярных языков. Делать 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.

Из этих ответов можно достичь более четкого понимания.

+4
источник

Вы можете использовать, 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
}
+3
источник

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

val value : String = "Kotlin"

value ?: ""

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

+1
источник

В Котлине нет тройного оператора.

В Kotlin, if является выражением, т.е. оно возвращает значение.

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

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

var a = if (a) b else c

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

+1
источник

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

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

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

when {
  a -> b
  else -> b
}
+1
источник

Если вам не нужно использовать стандартную нотацию, вы также можете создать/смоделировать ее, используя 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"
+1
источник

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

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

when(a) {
  true -> b
  false -> b
}
0
источник

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

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

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

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

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

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

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

0
источник

Пример: var energy: Int = data?.get(position)?. energy?.toInt()?: 0

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

0
источник
  • 1
  • 2

Посмотрите другие вопросы по меткам или Задайте вопрос