Qual é o equivalente dessa expressão no Kotlin?
a ? b : c
Este código não é válido no Kotlin.
Qual é o equivalente dessa expressão no Kotlin?
a ? b : c
Este código não é válido no Kotlin.
Respostas:
No Kotlin, if
declarações são expressões. Portanto, o seguinte código é equivalente:
if (a) b else c
A distinção entre expressão e afirmação é importante aqui. Em Java / C # / JavaScript, if
forma uma instrução, o que significa que ela não resolve para um valor. Mais concretamente, você não pode atribuí-lo a uma variável.
// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c
Se você vem de um idioma em que if
há uma declaração, isso pode parecer pouco natural, mas esse sentimento deve diminuir em breve.
when
.
x = a==b
b + if (a) c else d
vs. b + (c if (a) else d)
O último requer parênteses adicionais. porque c
não é delimitada pela condição e else
.
Você pode definir sua própria Boolean
função de extensão que retorna null
quando Boolean
for false
fornecer uma estrutura semelhante ao operador ternário:
infix fun <T> Boolean.then(param: T): T? = if (this) param else null
Isso faria uma a ? b : c
expressão ser traduzida para a then b ?: c
, assim:
println(condition then "yes" ?: "no")
Atualização: Mas, para fazer uma troca condicional semelhante a Java, você precisará de algo assim
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
preste atenção na lambda. seu cálculo de conteúdo deve ser adiada até que nós temos certeza condition
étrue
Este parece desajeitado, é por isso que existe uma solicitação muito alta para portar o operador ternário Java no Kotlin
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
?:
operador aqui é elvis-operator
: kotlinlang.org/docs/reference/null-safety.html#elvis-operator
if (a) b else c
é o que você pode usar em vez da expressão do operador ternário a ? b : c
.
Em Kotlin, muitas declarações de controle, incluindo if
, when
ou até mesmo try
pode ser usado como expressões . Isso significa que aqueles podem ter um resultado que pode ser atribuído a uma variável, retornado de uma função etc.
Como resultado das expressões de Kotlin, a linguagem realmente não precisa do operador ternário .
if (a) b else c
é o que você pode usar em vez da expressão do operador ternário a ? b : c
.
Penso que a ideia é que a expressão anterior seja mais legível, pois todo mundo sabe o que ifelse
faz, ao passo que não ? :
é claro se você ainda não conhece a sintaxe.
No entanto, tenho que admitir que muitas vezes sinto falta do operador ternário mais conveniente.
Outras alternativas
quando
Você também pode ver when
construções usadas no Kotlin quando as condições são verificadas. É também uma maneira de expressar o cascalho if-else de uma maneira alternativa. O seguinte corresponde ao exemplo do OTs.
when(a) {
true -> b
false -> c
}
Extensões
Como mostram muitos bons exemplos ( Operador condicional do Kotlin Ternary ) nas outras respostas, as extensões também podem ajudar na solução do seu caso de uso.
Para mim, eu uso as seguintes funções de extensão:
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
O primeiro retornará o valor padrão fornecido, caso o objeto seja igual a nulo. O segundo avaliará a expressão fornecida em lambda no mesmo caso.
Uso:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
Pessoalmente, para mim, o código acima é mais legível do que a if
construção embutida
e.getMessage() ?: "unknown"
. O segundo pode ser expresso comoobj?.lastMessage?.timestamp ?: { Date() }()
O equivalente em Java do operador ternário
a ? b : c
é um IF simples no Kotlin em uma linha
if(a) b else c
não há operador ternário (condição? então: mais), porque comum se funciona bem nesse papel.
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Caso especial para comparação nula
você pode usar o operador Elvis
if ( a != null ) a else b
// equivalent to
a ?: b
Não há operador ternário no kotlin, pois o if else
bloco retorna valor
então, você pode fazer: em
val max = if (a > b) a else b
vez de javamax = (a > b) ? b : c
Também podemos usar a when
construção, mas também retornamos valor:
val max = when(a > b) {
true -> a
false -> b
}
Aqui está o link para a documentação do kotlin: Fluxo de Controle: se, quando, por, enquanto
No Kotlin,
if
é uma expressão, ou seja, retorna um valor. Portanto, não há operador ternário(condition ? then : else)
, porque comum se funciona bem nesse papel. fonte manual daqui
// 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
Alguns casos de canto não mencionados em outras respostas.
Desde a aparência do takeIf no Kotlin 1.1, o operador ternário a ? b : c
também pode ser expresso assim:
b.takeIf { a } ?: c
Isso fica ainda mais curto caso c seja null
:
b.takeIf { a }
Observe também que, no mundo Java, as verificações nulas típicas, como value != null ? value : defaultValue
traduzir no otomático Kotlin para just value ?: defaultValue
.
Semelhante a != null ? b : c
pode ser traduzido para a?.let { b } ?: c
.
b.takeIf { a } ?: c
mais curto e mais legível do que if (a) b else c
? Terneray operador é certamente uma característica ausente em Kotlin desde nomes de variáveis ea condição pode ser longo e fazer você dividir a linha que é ruim
takeIf
sempre avalia o caso real (aqui a
). Essa expressão não só pode ser computada inutilmente se a
for falsa, mas você não pode se beneficiar de lançamentos inteligentes à la if (a is Int) { a + 3 }
.
{ a }
é um lambda avaliado preguiçosamente.
b
)". Mas mesmo { a }
sendo preguiçoso, deve ser avaliado para determinar o resultado da expressão.
Dê uma olhada nos documentos :
No Kotlin, se é uma expressão, ou seja, ele retorna um valor. Portanto, não há operador ternário (condição? Then: else), porque comum se funciona bem nesse papel.
Java
int temp = a ? b : c;
Equivalente a Kotlin:
var temp = if (a) b else c
TAREFA :
Vamos considerar o seguinte exemplo:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Precisamos do seguinte equivalente no Kotlin:
return (! answer.isSuccessful ())
?
"errado":
answer.body (). string ()
SOLUÇÕES :
1.a . Você pode usar if-expression
no Kotlin:
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1.b . Pode ser muito melhor se você virar isso if-expression
(vamos fazê-lo sem not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
2 . O operador Elvis da Kotlin ?:
pode fazer um trabalho ainda melhor:
return answer.body()?.string() ?: "wrong"
3 . Ou use um Extension function
para a Answer
classe correspondente :
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
4 . Usando o Extension function
você pode reduzir um código graças a Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
5 . Ou apenas use o when
operador:
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
Espero que isto ajude.
quando substitui o operador do comutador de idiomas do tipo C. Na forma mais simples, parece com isso
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
uma declaração, não uma expressão. Uma comparação mais relevante com expressões condicionais ternárias seria fazer com que cada ramificação retornasse um valor, de modo que a expressão quando inteira fosse avaliada como um valor (como acontece com as condicionais ternárias).
Não há operador ternário em Kotlin. Parece problemático à primeira vista. Mas pense que podemos fazê-lo com a instrução inline if else, porque esta é a expressão aqui. Simplesmente temos que fazer -
var number = if(n>0) "Positive" else "Negetive"
Aqui, podemos outra coisa se bloquearmos o número necessário. Gostar-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
Portanto, essa linha é tão simples e muito legível que o operador ternário. quando usamos mais de um operador ternário em java, isso parece horrível. Mas aqui temos uma sintaxe clara. até nós podemos escrever em várias linhas também.
Você pode usar var a= if (a) b else c
no lugar do operador ternário.
Outro bom conceito de kotlin é o operador de Elvis. Você não precisa verificar nulo sempre.
val l = b?.length ?: -1
Isso retornará length se b não for nulo, caso contrário, ele executará a instrução do lado direito.
como Drew Noakes citou, o kotlin usa if declaração como expressão, portanto o Operador Condicional Ternário não é mais necessário,
mas com a função de extensão e sobrecarga de infix, você pode implementar isso sozinho, aqui está um exemplo
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
}
então use-o assim
val grade = 90
val clazz = (grade > 80) then "A" or "B"
Outra abordagem interessante seria usar when
:
when(a) {
true -> b
false -> b
}
Pode ser bastante útil em alguns cenários mais complexos. E honestamente, é mais legível para mim do queif ... else ...
Você pode fazer isso de várias maneiras em Kotlin
Usando se
if(a) b else c
Usando quando
when (a) {
true -> print("value b")
false -> print("value c")
else -> {
print("default return in any other case")
}
}
Segurança nula
val a = b ?: c
Não existe uma operação ternária no Kotlin, mas existem algumas maneiras divertidas de contornar isso. Como outros já apontaram, uma tradução direta para o Kotlin seria assim:
val x = if (condition) result1 else result2
Mas, pessoalmente, acho que isso pode ficar um pouco confuso e difícil de ler. Existem outras opções embutidas na biblioteca. Você pode usar o takeIf {} com um operador elvis:
val x = result1.takeIf { condition } ?: result2
O que está acontecendo lá é que o comando takeIf {} retorna seu resultado1 ou nulo, e o operador elvis lida com a opção nula. Existem algumas opções adicionais, takeUnless {}, por exemplo:
val x = result1.takeUnless { condition } ?: result2
A linguagem é clara, você sabe o que está fazendo.
Se for uma condição comumente usada, você também pode fazer algo divertido, como usar um método de extensão em linha. Vamos supor que desejamos rastrear uma pontuação do jogo como um Int, por exemplo, e queremos sempre retornar 0 se uma determinada condição não for atendida:
inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this
Ok, isso parece feio. Mas considere como fica quando é usado:
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
Como você pode ver, o Kotlin oferece muita flexibilidade na maneira como você escolhe expressar seu código. Existem inúmeras variações dos meus exemplos e, provavelmente, maneiras que ainda nem descobri. Eu espero que isso ajude!
takeIf
é minha opção favorita, de fato, muito elegante.
Lembre-se de operador Ternary e operador Elvis possuem significados separados no Kotlin, diferentemente de muitos idiomas populares. Fazer expression? value1: value2
daria a você palavrões pelo compilador Kotlin , diferente de qualquer outro idioma, pois não há um operador ternário no Kotlin, conforme mencionado nos documentos oficiais . O motivo é que as próprias declarações if, when e try-catch retornam valores.
Então, fazer expression? value1: value2
pode ser substituído por
val max = if (a> b) print ("Escolha a") else print ("Escolha b")
O operador Elvis que Kotlin possui, funciona apenas no caso de variáveis anuláveis, ex .:
Se eu fizer algo assim
value3 = value1 ?: value2
, se value1 for nulo , value2 será retornado, caso contrário value1 seria retornado.
Um entendimento mais claro pode ser alcançado com essas respostas .
Você pode usar if
expressão para isso no Kotlin. No Kotlin if
é uma expressão com um valor de resultado. Então, em Kotlin, podemos escrever
fun max(a: Int, b: Int) = if (a > b) a else b
e em Java podemos conseguir o mesmo, mas com código maior
int max(int a, int b) {
return a > b ? a : b
}
Se você não fizer o que usar a notação padrão, também poderá criar / simular usando infix com algo como isto:
crie uma classe para manter sua meta e resultado:
data class Ternary<T>(val target: T, val result: Boolean)
crie algumas funções infix para simular uma operação ternária
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
}
Então você poderá usá-lo assim:
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"
Outra abordagem curta para usar
val value : String = "Kotlin"
value ?: ""
Aqui, o próprio kotlin verifica o valor nulo e, se for nulo, passa o valor da string vazia.
Por que alguém usaria algo assim:
when(a) {
true -> b
false -> b
}
quando você pode realmente usar algo assim ( a
neste caso, é booleano):
when {
a -> b
else -> b
}
? and :
contradiz com a declaração anulável / tipo, em vez de uma verificação de tipo. Além disso, não vejo motivo. Eu acho que alguém definitivamente pensaria um pouco, se houver uma verificação de condição em caso contrário. Vamos esperar e ver nas versões futuras.
Ao trabalhar com apply (), deixe parecer muito útil ao lidar com operações ternárias, pois é mais elegante e oferece espaço para você
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
Com as seguintes funções infix, posso cobrir muitos casos de uso comuns da mesma maneira que em 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
Não há operador ternário em Kotlin; os mais fechados são os dois casos abaixo,
val a = true if(a) print("A is true") else print("A is false")
Se a expressão à esquerda de?: Não for nula, o operador elvis a retornará, caso contrário, ela retornará a expressão à direita. Observe que a expressão do lado direito é avaliada apenas se o lado esquerdo for nulo.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
exemplo: var energy: Int = data? .get (position) ?. energy? .toInt ()?: 0
No kotlin, se você estiver usando ?: Funcionará como se a instrução retornasse nula, então :: 0 levará 0 ou o que quer que você tenha escrito deste lado.
No Kotlin você pode usar operações ternárias como esta: val x = if(a) "add b" else "add c"
Depois de pesquisar outras idéias, deduzi o seguinte operador ternário:
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
Exemplo (execute aqui ):
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")
}
}
Esta versão é fluente e não entra em conflito com o operador coalescente nulo.
then
vez de yes
.