Вопрос:

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

ternary-operator kotlin

38145 просмотра

29 ответа

187222 Репутация автора

Что является эквивалентом этого выражения в Kotlin?

a ? b : c

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

Автор: Drew Noakes Источник Размещён: 02.05.2013 11:07

Ответы (29)


442 плюса

187222 Репутация автора

Решение

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

Автор: Drew Noakes Размещён: 02.05.2013 11:08

31 плюса

4300 Репутация автора

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

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

Автор: ruX Размещён: 08.07.2015 03:41

22 плюса

1240 Репутация автора

Посмотрите на документы :

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

Автор: Li Ying Размещён: 28.07.2016 06:21

51 плюса

2172 Репутация автора

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

Автор: deviant Размещён: 25.09.2016 01:07

12 плюса

135 Репутация автора

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

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
Автор: Guruprasath Размещён: 23.05.2017 10:21

25 плюса

13622 Репутация автора

В Kotlin 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
Автор: Kris Roofe Размещён: 24.05.2017 05:30

7 плюса

308 Репутация автора

как цитировал Дрю Ноакс, kotlin использует оператор 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"
Автор: Minami Размещён: 07.06.2017 09:20

11 плюса

664 Репутация автора

В Котлине нет троичного оператора. Это кажется проблематичным на первый взгляд. Но подумайте, что мы можем сделать это с помощью встроенного оператора if, потому что это выражение здесь. Просто мы должны сделать -

var number = if(n>0) "Positive" else "Negetive"

Здесь мы можем еще, если заблокировать слишком много, сколько нам нужно. Подобно-

var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"

Так что эта строка настолько проста и намного удобочитаемее, чем троичный оператор. когда мы используем более одного троичного оператора в Java, это кажется ужасным. Но здесь у нас есть четкий синтаксис. даже мы можем написать это в несколько строк.

Автор: HM Nayem Размещён: 09.06.2017 10:40

21 плюса

15055 Репутация автора

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

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

b.takeIf { a } ?: c

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

b.takeIf { a }

Также обратите внимание, что типичные в мире Java проверки value != null ? value : defaultValueна ноль, такие как перевод в идеологическом Kotlin, просто value ?: defaultValue.

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

Автор: Vadzim Размещён: 11.06.2017 12:30

14 плюса

196 Репутация автора

Джава

int temp = a ? b : c;

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

var temp = if (a) b else c
Автор: doubleThunder Размещён: 27.06.2017 03:14

6 плюса

7738 Репутация автора

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

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

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

Автор: Grzegorz Piwowarek Размещён: 26.07.2017 06:59

26 плюса

456 Репутация автора

В kotlin нет троичного оператора , так как if elseблок возвращает значение

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

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

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

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

Автор: romiope Размещён: 26.07.2017 08:05

2 плюса

716 Репутация автора

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

val value : String = "Kotlin"

value ?: ""

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

Автор: Vinod Pattanshetti Размещён: 22.09.2017 09:32

7 плюса

535 Репутация автора

Вы можете сделать это по-разному в Kotlin

  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
    
Автор: Rajesh Dalsaniya Размещён: 02.10.2017 06:33

32 плюса

27406 Репутация автора

TL; DR

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


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

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

В результате Котлину не нужен троичный оператор .

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

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


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

когда

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

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

расширения

Как показывают многие хорошие примеры ( Kotlin Ternary Conditional Operator ) в других ответах, расширения также могут быть подходящим вариантом.

Автор: s1m0nw1 Размещён: 20.10.2017 06:20

1 плюс

1461 Репутация автора

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

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

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

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

var a = if (a) b else c

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

Автор: Gowtham Subramaniam Размещён: 13.11.2017 06:00

0 плюса

574 Репутация автора

Со следующими инфиксными функциями я могу охватить многие распространенные случаи использования практически так же, как это можно сделать в 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
Автор: Nicolas Cornette Размещён: 17.11.2017 03:55

3 плюса

203 Репутация автора

Вы можете использовать ifвыражение для этого в Kotlin. В 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
}
Автор: Gulzar Bhat Размещён: 06.01.2018 09:41

0 плюса

1257 Репутация автора

При работе с 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
}
Автор: Juan Mendez Размещён: 28.01.2018 11:51

4 плюса

41 Репутация автора

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

val x = if (condition) result1 else result2

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

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

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

Автор: pranalli Размещён: 04.02.2018 09:06

0 плюса

21 Репутация автора

используйте условный оператор if-else или оператор

when(a) {
  true -> b
  false -> b
}
Автор: cleaning agent Размещён: 06.05.2018 03:05

0 плюса

746 Репутация автора

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

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

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

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

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

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

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

Автор: JTeam Размещён: 02.07.2018 10:58

0 плюса

133 Репутация автора

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

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

Автор: abhilasha Yadav Размещён: 19.07.2018 06:38

2 плюса

591 Репутация автора

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

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

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

when {
  a -> b
  else -> b
}
Автор: ZZ 5 Размещён: 24.07.2018 11:40

5 плюса

793 Репутация автора

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

var d = if (a) b else c
Автор: dey Размещён: 27.07.2018 02:24

0 плюса

0 Репутация автора

var a:Int=20
var b:Int=5
val c:Int=15

var d=if(a>b)a else c
print("Output is: $d")
Автор: user10480468 Размещён: 10.10.2018 08:41

6 плюса

191 Репутация автора

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

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

val l = b?.length ?: -1

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

Автор: Android Geek Размещён: 25.10.2018 06:58

2 плюса

5374 Репутация автора

ЗАДАЧА :

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

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

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

return (! answer.isSuccessful ()) ? «неправильно» : answer.body (). string ()

введите описание изображения здесь

РЕШЕНИЯ :

1.а . Вы можете использовать if-expressionв Kotlin:

return if (!answer.isSuccessful()) "wrong" else answer.body().string()

. Может быть намного лучше, если вы перевернете это 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()
}

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

Автор: ARGeo Размещён: 09.01.2019 04:26

0 плюса

1 Репутация автора

В Kotlin, если поток управления является выражением. Итак, он возвращает значение. Следовательно, Котлин не предоставляет троичного оператора (условие? Тогда: еще). Итак, мы можем написать эквивалентный код.

var v=if(a) b else c 
Автор: Ahasan Размещён: 23.02.2019 05:57
Вопросы из категории :
32x32