Kotlinでこの表現に相当するものは何ですか?
a ? b : c
これはKotlinでは有効なコードではありません。
Kotlinでこの表現に相当するものは何ですか?
a ? b : c
これはKotlinでは有効なコードではありません。
回答:
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
ステートメントがである言語から来ている場合、これは不自然に見えるかもしれませんが、その感覚はすぐに収まるはずです。
when
。
x = a==b
b + if (a) c else d
対b + (c if (a) else d)
後者は追加の括弧が必要です。c
条件に囲まれていないためですelse
。
独自に定義でき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の三項演算子をKotlinに移植するという要求の強い要求があります。
infix inline fun<T> Boolean.then(param: ()->T):T? = if(this) param() else null
true then { null } ?: "not-null"
if (a) b else c
三項演算子式の代わりに使用できるものですa ? b : c
。
Kotlinでは、を含む多くの制御ステートメントif
、when
または式try
としても使用できます。これは、それらが変数に割り当てられたり、関数などから返されたりする結果を持つ可能性があることを意味します。
Kotlinの式の結果として、言語は実際には三項演算子を必要としません。
if (a) b else c
三項演算子式の代わりに使用できるものですa ? b : c
。
誰もが何を知っているので、前の表現はもっと読みやすいという考えだと思います ifelse
が、? :
既に構文に慣れていないのであれば、むしろ不明です。
それにもかかわらず、私はより便利な三項演算子をしばしば見逃していることを認めざるを得ません。
他の選択肢
いつ
またwhen
、条件がチェックされるときにKotlinで使用される構成が表示される場合もあります。また、if-elseカスケードを別の方法で表現する方法でもあります。以下は、OTの例に対応しています。
when(a) {
true -> b
false -> c
}
拡張
他の回答の多くの良い例(Kotlin Ternary Conditional Operator)が示すように、拡張機能はユースケースの解決にも役立ちます。
私自身は、次の拡張関数を使用しています。
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つ目は、オブジェクトがnullの場合に提供されたデフォルト値を返します。2番目は、同じケースでラムダで提供される式を評価します。
使用法:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
個人的には、上記のコードはif
構文のインライン化よりも読みやすい
e.getMessage() ?: "unknown"
ます。2番目は次のように表すことができますobj?.lastMessage?.timestamp ?: { Date() }()
Javaの三項演算子に相当するもの
a ? b : c
Kotlinの1行の単純なIF
if(a) b else c
通常のifがこの役割でうまく機能するため、3項演算子(条件?then:else)はありません。
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
Null比較の特殊なケース
Elvis演算子を使用できます
if ( a != null ) a else b
// equivalent to
a ?: b
ブロックは値を返すため、kotlinには三項演算子はありませんif else
だから、あなたは行うことができます:
val max = if (a > b) a else b
javaの代わりにmax = (a > b) ? b : c
when
構築を使用することもでき、値も返します。
val max = when(a > b) {
true -> a
false -> b
}
ここにkotlinのドキュメントへのリンクがあります:制御フロー:if、when、for、while
他の回答で言及されていないいくつかのコーナーケース。
出現以来takeIfでKotlin 1.1三オペレータはa ? b : c
、このように表現することができます。
b.takeIf { a } ?: c
cがnull
次の場合、これはさらに短くなります。
b.takeIf { a }
また、Javaの世界はnullチェックの典型的には好きなことをノートvalue != null ? value : defaultValue
だけにideomatic Kotlinに変換しますvalue ?: defaultValue
。
同様にa != null ? b : c
に翻訳できますa?.let { b } ?: c
。
b.takeIf { a } ?: c
短くて読みやすいですif (a) b else c
か?Terneray演算子は確かに変数名からKotlinで不足している機能であり、状態が長くなると、あなたが悪いの行を分割することができます
takeIf
常にtrue-caseを評価する(ここa
)。a
たまたま偽の場合、その式が無用に計算される可能性があるだけでなく、スマートキャストアラの恩恵を受けることもできませんif (a is Int) { a + 3 }
。
{ a }
遅延評価されたラムダです。
b
)」。しかし、でも{ a }
、怠惰であるにもかかわらず、式の結果を決定するために評価する必要があります。
ジャワ
int temp = a ? b : c;
Kotlinと同等:
var temp = if (a) b else c
タスク:
次の例を考えてみましょう:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
Kotlinには次の同等のものが必要です。
return(!answer.isSuccessful())
?
"間違った":
answer.body()。string()
ソリューション:
1.A。if-expression
Kotlinで使用できます。
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のElvisオペレーター?:
は、より良い仕事をすることができます:
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()
}
お役に立てれば。
Cのような言語のスイッチ演算子を置き換える場合。最も単純な形では次のようになります
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> {
print("x is neither 1 nor 2")
}
}
when
はステートメントではなく、式として持っています。三項条件式とのより適切な比較は、各ブランチに値を返すようにすることです。これにより、(三項条件式で発生するように)when式全体が値に評価されます。
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で複数の三項演算子を使用すると、恐ろしいように見えます。しかし、ここには明確な構文があります。複数行で書くこともできます。
var a= if (a) b else c
三項演算子の代わりに使用できます。
Kotlinのもう1つの優れた概念は、Elvisオペレーターです。毎回nullをチェックする必要はありません。
val l = b?.length ?: -1
bがnullでない場合は長さを返し、そうでない場合は右側のステートメントを実行します。
Drew Noakesが引用したように、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"
別の興味深いアプローチは、使用することwhen
です:
when(a) {
true -> b
false -> b
}
より複雑なシナリオでは非常に便利です。そして正直なところ、私にとってはif ... else ...
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
Kotlinには3項演算はありませんが、これを回避する楽しい方法がいくつかあります。他の人が指摘したように、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
OK、それは醜いようです。ただし、使用時の外観を考慮してください。
var score = 0
val twoPointer = 2
val threePointer = 3
score += twoPointer.zeroIfFalse { scoreCondition }
score += threePointer.zeroIfFalse { scoreCondition }
ご覧のとおり、Kotlinはコードの表現方法を柔軟に選択できます。私の例には無数のバリエーションがあり、おそらく私がまだ発見していない方法もあります。これが役に立てば幸いです!
takeIf
本当に私のお気に入りのオプションです。とてもエレガントです。
Ternary演算子とElvis演算子は、多くの一般的な言語とは異なり、Kotlinでは異なる意味を持っていることを覚えておいてください。こうexpression? value1: value2
することによって、あなたに悪い言葉を与えるだろうKotlinのがないので、他の言語とは異なり、コンパイラKotlinには三項演算子で述べたように公式ドキュメントが。その理由は、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
をした場合、value1がnullの場合はvalue2が返され、それ以外の場合はvalue1が返されます。
標準表記を使用しない場合は、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"
使用する別の短いアプローチ
val value : String = "Kotlin"
value ?: ""
ここでは、kotlin自体がnull値をチェックし、nullの場合は空の文字列値を渡します。
なぜこのようなものを使用するのですか?
when(a) {
true -> b
false -> b
}
あなたが実際にこのようなものを使用できるとき(a
この場合はブール値です):
when {
a -> b
else -> b
}
? and :
型チェックではなく、nullable /型宣言と矛盾すると思います。それ以外は何の理由もありません。インラインif-else条件チェックがあれば、誰かが間違いなくいくつかのことを考えたでしょう。待って、将来のバージョンで見てみましょう。
次のインフィックス関数を使用すると、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
Kotlinには三項演算子はありません。最も閉じているのは、以下の2つのケースです。
val a = true if(a) print("A is true") else print("A is false")
?:の左側の式がnullでない場合、elvis演算子はそれを返します。それ以外の場合は、右側の式を返します。右側の式は、左側がnullの場合にのみ評価されることに注意してください。
val name = node.getName() ?: throw IllegalArgumentException("name expected")
Kotlinでは、次のような3項演算を使用できます。 val x = if(a) "add b" else "add c"
他のアイデアを調査した後、次の3項演算子を導出しました。
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
例(ここで実行):
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の合体演算子と競合しません。
then
代わりに名前が付けられている逸脱者の回答と同じですyes
。