web-dev-qa-db-ja.com

コトリン三項条件演算子

Kotlinでこの式に相当するものは何ですか?

a ? b : c

これはKotlinの有効なコードではありません。

345
Drew Noakes

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がステートメントである言語から来ている場合、これは不自然に見えるかもしれませんが、その感覚はすぐに収まるはずです。

490
Drew Noakes

Booleannullのときに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")はラムダに注意を払います。 conditiontrueであることを確認するまで、そのコンテンツの計算を延期する必要があります

これは不格好に見えます だからJava三項演算子をKotlinに移植するために高い要求があります

55
deviant

TL; DR

if (a) b else cは、Java式a ? b : cの代わりに使用できるものです。


Kotlinでは、ifwhen、またはtryを含む多くの制御ステートメントをexpressionsとして使用できます。これは、それらが変数に割り当てられ、関数などから返される結果を持つことができることを意味します。

構文的に、三項演算子は不要

その結果、Kotlinは三項演算子を必要としません。

if (a) b else cは、Java式a ? b : cの代わりに使用できるものです。

後者は、ifelseが何をするか知っているので、後者は読みにくいと思いますが、構文に慣れていない場合は? :はかなり不便です。私は、より便利な三項演算子をしばしば見逃していることを認めなければなりませんが。


その他の選択肢

when

また、Kotlinで条件がチェックされるたびに、多くのwhenコンストラクトが表示される場合があります。また、if-elseカスケードを別の方法で表現する方法でもあります。以下はあなたの例に対応しています。

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

拡張機能

他の回答の多くの良い例( Kotlin Ternary Conditional Operator )に示されているように、拡張機能を使用することもできます。

37
s1m0nw1

私自身は、次の拡張機能を使用します。

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に等しい場合に提供されたデフォルト値を返します。 2番目は、同じ場合にラムダで提供される式を評価します。

使用法:

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

個人的には、if構築インライン化よりも読みやすい上記のコード

32
ruX

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
26
Kris Roofe

if elseブロックは値を返すため、kotlinには三項演算子はありません

javaのval max = if (a > b) a else bの代わりにmax = (a > b) ? b : cを実行できます

when構造も使用できます。また、値を返します。

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

Kotlinドキュメントのリンクは次のとおりです。 制御フロー:if、when、for、while

26
romiope

docs を見てください:

Kotlinでは、ifが式である、つまり値を返します。したがって、通常のifはこの役割で正常に機能するため、三項演算子(条件?then:else)はありません。

22
Li Ying

他の回答で言及されていないいくつかのコーナーケース。

takeIf in Kotlin 1.1 の出現から、三項演算子a ? b : cは次のようにも表現できます。

b.takeIf { a } ?: c

Cがnullの場合、これはさらに短くなります。

b.takeIf { a }

また、Javaの世界では典型的なvalue != null ? value : defaultValueのようなnullチェックは、イデオマティックKotlinでvalue ?: defaultValueに変換することに注意してください。

同様のa != null ? b : cは、a?.let { b } ?: cに変換できます。

21
Vadzim

Java

int temp = a ? b : c;

コトリンと同等:

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

cに似た言語のスイッチ演算子を置き換えるとき。最も単純な形式では、次のようになります

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

Kotlinには三項演算子はありません。一見問題があるようです。ただし、これはここでの式なので、インラインif elseステートメントを使用して実行できると考えます。単純にやらなければならないこと-

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

ここで、必要に応じてブロックしすぎると、他のことができます。いいね

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

したがって、この行は、三項演算子よりも非常にシンプルで読みやすいです。 Javaで複数の三項演算子を使用すると、恐ろしいように見えます。しかし、ここには明確な構文があります。複数行で書くこともできます。

11
HM Nayem

drew Noakesが引用したように、kotlinはifステートメントを式として使用するため、Ternary Conditional Operatorは必要なくなり、

しかし、拡張機能と中置のオーバーロードを使用すると、それを自分で実装できます。ここに例を示します

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"
8
Minami

Kotlinでさまざまな方法で行うことができます

  1. Ifを使用する

    if(a) b else c
    
  2. Whenを使用する

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
    
  3. ヌルの安全性

    val a = b ?: c
    
7

三項演算子の代わりにvar a= if (a) b else cを使用できます。

Kotlinのもう1つの優れたコンセプトは、エルビスオペレーターです。毎回nullをチェックする必要はありません。

val l = b?.length ?: -1

これは、bがnullでない場合に長さを返し、そうでない場合は右側のステートメントを実行します。

6
Android Geek

別の興味深いアプローチは、whenを使用することです。

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

より複雑なシナリオでは非常に便利です。正直なところ、if ... else ...よりも読みやすい

6

kotlinには三項演算子はありません。そのためif式があります:

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

タスク

次の例を考えてみましょう。

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

Kotlinには次のものが必要です。

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

enter image description here

ソリューション

1.a。 Kotlinでif-expressionを使用できます。

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

1.b。このif-expressionを反転すると、はるかに優れたものになります(notなしで実行しましょう)。

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

2。 Kotlinのエルビスオペレーター?:はさらに良い仕事をすることができます。

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

3。または、対応するAnswerクラスにExtension functionを使用します。

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

4Extension functionを使用すると、Elvis operatorのおかげでコードを削減できます。

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

5。または、単にwhen演算子を使用します。

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

お役に立てれば。

5
ARGeo

Kotlinには三項演算はありませんが、それを回避するための楽しい方法がいくつかあります。他の人が指摘しているように、Kotlinへの直接翻訳は次のようになります。

val x = if (condition) result1 else result2

しかし、個人的には、それは少し混乱して読みにくくなると思います。ライブラリには他にもいくつかのオプションが組み込まれています。 elvis演算子で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は、コードの表現方法を柔軟に選択できます。私の例には無数のバリエーションがあり、おそらく私がまだ発見していない方法もあります。これがお役に立てば幸いです!

4
pranalli

Kotlinでは、このために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
Gulzar Bhat

三項演算子およびエルビス演算子は、多くの一般的な言語とは異なり、Kotlinで別々の意味を保持する。 expression? value1: value2を実行すると、Kotlinコンパイラーによって不適切な単語が表示されます。他の言語とは異なり、 Kotlin には3項演算子はありません 公式ドキュメント 。その理由は、 if、when、およびtry-catch ステートメント自体が値を返すためです。

したがって、expression? value1: value2を行うことは、

val max = if(a> b)print( "Choose a")else print( "Choose b")

エルビス演算子Kotlinは、null許容変数exの場合にのみ機能します。

value3 = value1 ?: value2のようなことをすると、value1nullの場合、value2はそうでなければ返されますvalue1が返されます。

これらの回答 からより明確な理解を得ることができます。

3
neer17

使用する別の短いアプローチ

val value : String = "Kotlin"

value ?: ""

ここでは、kotlin自体がnull値をチェックし、nullの場合は空の文字列値を渡します。

2

Kotlinでは、制御フローが式の場合。したがって、値を返します。そのため、Kotlinは三項演算子を提供しません(条件?その後:else)。したがって、同等のコードを書くことができます。

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

なぜこのようなものを使用するのでしょうか:

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

実際に次のようなものを使用できる場合(この場合、aはブール値です):

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

Kotlinには、三項演算子はありません。

Kotlinでは、ifが式である、つまり値を返します。

したがって、通常のifはこの役割で正常に機能するため、三項演算子(条件?then:else)はありません。

Kotlinで同等

var a = if (a) b else c

参照ドキュメント制御フロー:if、when、for、while

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

Javaの三項演算子に相当

a ? b : c

kotlinの1行のシンプルなIF

if(a) b else c

通常のifはこの役割でうまく機能するため、三項演算子(条件?then:else)はありません。

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

0
Raymond Chenon

Apply()を使用する場合、3項演算を処理するときに非常に便利であるようにしましょう。これはよりエレガントで余裕があるためです。

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

例:var energy:Int = data?.get(position)?. energy?.toInt()?:

Kotlinで?:を使用している場合、ステートメントがnullを返す場合と同様に動作します?: 0またはこの側を書いたものが必要です。

0
abhilasha Yadav

他のアイデアをいくつか調査した後、次の三項演算子を導き出しました。

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

例(実行 here ):

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

このバージョンは流で、null合体演算子と競合しません。

0
Bryan W. Wagner

Kotlinには三項演算子はありません。最も閉じているのは以下の2つの場合です。

  • 式ステートメントとしてif else

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

  • エルビス演算子

?:の左側の式がnullでない場合、elvis演算子はそれを返し、そうでない場合は右側の式を返します。右側の式は、左側がヌルの場合にのみ評価されることに注意してください。

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

リファレンスドキュメント

0
JTeam

次の挿入関数を使用すると、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

if-else条件ステートメントまたはwhen演算子を次のように使用します

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