web-dev-qa-db-fra.com

Opérateur conditionnel ternaire de Kotlin

Quel est l'équivalent de cette expression en kotlin?

a ? b : c

Ce n'est pas un code valide dans Kotlin.

301
Drew Noakes

En Kotlin, les instructions if sont des expressions. Donc, le code suivant est équivalent:

if (a) b else c

La distinction entre expression et énoncé est importante ici. En Java/C #/JavaScript, if forme une instruction, ce qui signifie qu'elle ne se résout pas en une valeur. Plus concrètement, vous ne pouvez pas l'affecter à une variable.

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

Si vous venez d'une langue où if est une déclaration, cela peut sembler anormal mais ce sentiment devrait bientôt disparaître.

443
Drew Noakes

TL; DR

if (a) b else c est ce que vous pouvez utiliser à la place de l'expression Java a ? b : c


Dans Kotlin, de nombreuses instructions de contrôle, telles que if, when ou même try, peuvent être utilisées comme expressions. Cela signifie que ceux-ci peuvent avoir un résultat qui peut être affecté à une variable, renvoyé d'une fonction, etc.

Syntaxiquement, pas besoin d'opérateur ternaire

En conséquence, Kotlin n'a pas besoin de l'opérateur ternaire.

if (a) b else c est ce que vous pouvez utiliser à la place de l'expression Java a ? b : c

Je pense que l'idée est que ce dernier est moins lisible puisque tout le monde sait ce que fait ifelse, alors que ? : est plutôt gênant si vous ne connaissez pas déjà la syntaxe. Bien que je dois admettre que l’opérateur ternaire, plus pratique, me manque souvent.


Autres alternatives

quand

Vous pouvez également voir beaucoup de constructions when lorsque les conditions sont vérifiées dans Kotlin. C'est aussi un moyen d'exprimer les cascades if-else d'une manière alternative. Ce qui suit correspond à votre exemple.

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

Extensions

Comme le montrent de nombreux bons exemples ( Opérateur conditionnel ternaire de Kotlin ) dans les autres réponses, les extensions peuvent également être une voie à suivre. 

32
s1m0nw1

J'utilise pour moi les fonctions d'extension suivantes:

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

Le premier retourne la valeur par défaut fournie dans le cas où l'objet est égal à null. Deuxièmement, nous évaluerons l'expression fournie dans lambda dans le même cas.

Usage:

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

Personnellement, le code ci-dessus est plus lisible que if construction inlining

31
ruX

Il n'y a pas d'opérateur ternaire dans kotlin, car le bloc if else renvoie la valeur

alors, vous pouvez faire: val max = if (a > b) a else b au lieu de max = (a > b) ? b : c de Java

Nous pouvons également utiliser la construction when, elle renvoie également une valeur:

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

Voici un lien vers la documentation de kotlin: Flux de contrôle: if, when, for, while

26
romiope

if est une expression dans Kotlin, c’est-à-dire qu’elle renvoie une valeur. Donc il n'y a pas d'opérateur ternaire (condition ? then : else), car ordinaire si fonctionne très bien dans ce rôle. source manuelle d'ici

// 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
25
Kris Roofe

Jetez un coup d'œil aux docs :

En Kotlin, si est une expression, c’est-à-dire qu’elle renvoie une valeur. Donc là n’existe pas d’opérateur ternaire (condition? then: else), parce que ordinaire si fonctionne très bien dans ce rôle.

22
Li Ying

Quelques cas non mentionnés dans d'autres réponses.

Depuis l'apparition de takeIf in Kotlin 1.1 , l'opérateur ternaire a ? b : c peut également être exprimé comme suit:

b.takeIf { a } ?: c

Cela devient encore plus court si c est null:

b.takeIf { a }

Notez également que dans le monde Java, des contrôles nuls tels que value != null ? value : defaultValue se traduisent en Kotlin idéomatique en value ?: defaultValue uniquement.

a != null ? b : c similaire peut être traduit en a?.let { b } ?: c.

21
Vadzim

Java 

int temp = a ? b : c;

Équivalent à Kotlin :

var temp = if (a) b else c
14
doubleThunder

quand remplace l'opérateur de commutation des langages de type C. Dans la forme la plus simple, cela ressemble à ceci

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

Il n'y a pas d'opérateur ternaire à Kotlin. Cela semble problématique au premier abord. Mais pensons que nous pouvons le faire avec une déclaration inline if else car il s’agit d’une expression ici. Nous devons simplement faire -

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

Ici, nous pouvons aussi bloquer si nous en avons trop. Comme-

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

Cette ligne est tellement simple et lisible que l’opérateur ternaire. lorsque nous utilisons plus d’un opérateur ternaire en Java, cela semble horrible. Mais ici nous avons une syntaxe claire. nous pouvons même l'écrire sur plusieurs lignes. 

11
HM Nayem

comme cité par Drew Noakes, kotlin utilise if comme instruction, Ainsi, l'opérateur conditionnel ternaire n'est plus nécessaire,

mais avec la fonction d'extension et la surcharge infixe, vous pouvez l'implémenter vous-même, voici un exemple

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
}

puis utilisez-le comme ça

val grade = 90
val clazz = (grade > 80) then "A" or "B"
7
Minami

Vous pouvez le faire de nombreuses façons à Kotlin

  1. Utiliser si

    if(a) b else c
    
  2. Utiliser quand

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
    
  3. Sécurité Null

    val a = b ?: c
    
7
Rajesh Dalsaniya

Vous pouvez utiliser var a= if (a) b else c à la place de l'opérateur ternaire.

Elvis est un autre bon concept de kotlin. Vous n'avez pas besoin de vérifier null à chaque fois.

val l = b?.length ?: -1

Cela retournera la longueur si b n'est pas null, sinon il exécutera l'instruction de droite.

6
Android Geek

Une autre approche intéressante serait d’utiliser when:

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

Peut être assez pratique dans certains scénarios plus complexes. Et honnêtement, c'est plus lisible que if ... else ...

6
Grzegorz Piwowarek

il n'y a pas d'opérateur ternaire dans Kotlin, car il y a si expression:

var d = if (a) b else c
5
dey

Il n’ya pas d’opération ternaire à Kotlin, mais il existe des moyens amusants de contourner ce problème. Comme d'autres l'ont souligné, une traduction directe en Kotlin ressemblerait à ceci:

val x = if (condition) result1 else result2

Mais, personnellement, je pense que cela peut devenir un peu encombré et difficile à lire. Il y a d'autres options intégrées dans la bibliothèque. Vous pouvez utiliser takeIf {} avec un opérateur elvis:

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

Ce qui se passe là-bas, c'est que la commande takeIf {} renvoie soit result1, soit null, et l'opérateur elvis gère l'option null. Il y a quelques options supplémentaires, takeUnless {}, par exemple:

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

Le langage est clair, vous savez ce que cela fait. 

S'il s'agit d'une condition couramment utilisée, vous pouvez également faire quelque chose de amusant, comme utiliser une méthode d'extension en ligne. Supposons, par exemple, que nous voulions suivre le score d'un jeu en tant qu'Int et que nous voulions toujours renvoyer 0 si une condition donnée n'est pas remplie:

inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this     

Ok, ça semble moche. Mais considérez à quoi il ressemble quand il est utilisé:

var score = 0
val twoPointer = 2
val threePointer = 3

score += twoPointer.zeroIfFalse { scoreCondition } 
score += threePointer.zeroIfFalse { scoreCondition } 

Comme vous pouvez le constater, Kotlin vous offre une grande flexibilité dans la manière dont vous choisissez d’exprimer votre code. Il existe d'innombrables variantes de mes exemples et probablement des moyens que je n'ai pas encore découverts. J'espère que ça aide! 

4
pranalli

Vous pouvez utiliser l'expression if pour cela dans Kotlin. Dans Kotlin, if est une expression avec une valeur de résultat. Donc, à Kotlin, nous pouvons écrire

fun max(a: Int, b: Int) = if (a > b) a else b

et en Java, nous pouvons réaliser la même chose, mais avec un code plus gros

int max(int a, int b) {
return a > b ? a : b
}
3
Gulzar Bhat

T&ACIRC;CHE:

Considérons l'exemple suivant:

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

Nous avons besoin de l'équivalent suivant en Kotlin:

return (! answer.isSuccessful ())?"faux":answer.body (). string ()

 enter image description here

SOLUTIONS:

1.a. Vous pouvez utiliser if-expression dans Kotlin:

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

1.b. Cela peut être beaucoup mieux si vous retournez ce if-expression (faisons le sans not):

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

2. L’opérateur Kotlin ’Elvis ?: peut encore mieux faire un travail:

return answer.body()?.string() ?: "wrong"

3. Ou utilisez un Extension function pour la classe Answer correspondante:

fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null

4. En utilisant le Extension function, vous pouvez réduire un code grâce à Elvis operator:

return answer.bodyOrNull()?.string() ?: "wrong"

5. Ou utilisez simplement l'opérateur when:

when (!answer.isSuccessful()) {
    parseInt(str) -> result = "wrong"
    else -> result = answer.body().string()
}

J'espère que cela t'aides.

3
ARGeo

Rappelez-vous Opérateur ternaire et Opérateur Elvis conserve des significations distinctes en Kotlin contrairement à de nombreux langages populaires. Faire expression? value1: value2 vous donnerait des gros mots de la part du compilateur Kotlin, contrairement à tout autre langage puisqu'il n'y a aucun opérateur ternaire dans Kotlin comme indiqué dans le document officiel . que les instructions if, when et try-catch renvoient elles-mêmes des valeurs.

Donc, faire expression? value1: value2 peut être remplacé par

val max = if (a> b) print ("Choisir un") sinon print ("Choisir b")

L'opérateur Elvis that Kotlin _ fonctionne uniquement dans le cas de variables nullable, par exemple:

Si je fais quelque chose comme value3 = value1 ?: value2, alors si valeur1 est null, alors valeur2 serait renvoyé, sinon valeur1 serait renvoyé.

Une compréhension plus claire peut être obtenue à partir de ces réponses .

3
neer17

Une autre approche courte à utiliser 

val value : String = "Kotlin"

value ?: ""

Ici, Kotlin lui-même vérifie la valeur NULL et si elle est NULL, elle transmet la valeur de chaîne vide.

2
Vinod Pattanshetti

Pourquoi utiliserait-on quelque chose comme ceci:

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

quand vous pouvez réellement utiliser quelque chose comme ceci (a est boolean dans ce cas):

when {
  a -> b
  else -> b
}
2
ZZ 5

En Kotlin, il n’existe aucun opérateur ternaire.

En Kotlin, si est une expression, c’est-à-dire qu’elle renvoie une valeur.

Il n’ya donc pas d’opérateur ternaire (condition? Then: else), parce que ordinaire si fonctionne très bien dans ce rôle.

Équivalent en Kotlin 

var a = if (a) b else c

Document de référence: Flux de contrôle: si, quand, pour, tandis que

1

Si vous ne savez pas quoi utiliser la notation standard, vous pouvez aussi la créer/la simuler en utilisant infix avec quelque chose comme:

créer une classe pour contenir votre cible et résultat:

data class Ternary<T>(val target: T, val result: Boolean)

créer des fonctions infixes pour simuler une opération ternaire

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
}

Ensuite, vous pourrez l'utiliser comme ceci:

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
Eudy Contreras

En Kotlin, si le flux de contrôle est une expression. Donc, cela retourne une valeur. Kotlin ne fournit donc pas d’opérateur ternaire (condition? Then: else). Nous pouvons donc écrire le code équivalent.

var v=if(a) b else c 
1
Ahasan

L'équivalent Java de l'opérateur ternaire

a ? b : c

est un simple IF à Kotlin en une ligne

if(a) b else c

il n'y a pas d'opérateur ternaire (condition? then: else), car ordinaire si fonctionne très bien dans ce rôle.

https://kotlinlang.org/docs/reference/control-flow.html#if-expression

0
Raymond Chenon

Lorsque vous travaillez avec apply (), laissez paraître très pratique lorsque vous travaillez avec des opérations ternaires, car il est plus élégant et vous laisse de la place.

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
Juan Mendez

exemple: var énergie: Int = données? .get (position)?. énergie? .toInt ()?: 0

En kotlin, si vous utilisez?: cela fonctionnera comme si l'instruction retournait null alors?: 0 cela prend 0 ou tout ce que vous avez écrit pour écrire ce côté.

0
abhilasha Yadav

Après quelques recherches sur d'autres idées, j'ai tiré l'opérateur ternaire suivant:

infix fun <T : Any> Boolean.yes(trueValue: T): T? = if (this) trueValue else null
infix fun <T : Any> T?.no(falseValue: T): T = this ?: falseValue

Exemple (exécutez ici ):

fun main() {
    run {
        val cond = true
        val result = cond yes "True!" no "False!"
        println("ternary test($cond): $result")
    }
    run {
        val cond = false
        val result = cond yes "True!" no "False!"
        println("ternary test($cond): $result")
    }
}

Cette version est fluide et n'entre pas en conflit avec l'opérateur de coalescence nul.

0
Bryan W. Wagner

Avec les fonctions infixes suivantes, je peux couvrir de nombreux cas d'utilisation courants à peu près de la même façon que cela peut être fait en 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
Nicolas Cornette

utilisez l'instruction conditionnelle if-else ou l'opérateur operator comme suit

when(a) {
  true -> b
  false -> b
}
0
cleaning agent
var a:Int=20
var b:Int=5
val c:Int=15

var d=if(a>b)a else c
print("Output is: $d")
0
user10480468