回答:
次のlet
ように-function を使用できます。
val a = b?.let {
// If b is not null.
} ?: run {
// If b is null.
}
run
コードのブロックが必要な場合にのみ、関数を呼び出す必要があることに注意してください。run
elvis-operator(?:
)の後にonelinerしかない場合は、-blockを削除できます。
あることに注意してくださいrun
場合、ブロックはいずれかで評価されますb
nullである場合、またはlet
-ブロック評価さへnull
。
このため、通常はif
式だけが必要です。
val a = if (b == null) {
// ...
} else {
// ...
}
この場合、else
-blockは、b
がnullでない場合にのみ評価されます。
a
let
およびのスコープ内ではまだ定義されていませんrun
。ただし、暗黙的なパラメータを使用して、b
内部の値にアクセスできlet
ますit
。これは私が推測するのと同じ目的を果たします。
a
これらのコードブロックの前にの割り当てを完了します。そして、a
内部にアクセスすることができます。
a
ますか?それはだ場合b
、その後、it
まったく同じ目的を果たします。-block a
の結果で再割り当てされval
ますか?
it
内からのみアクセスできますlet
。let
or run
ブロックの結果はに割り当てられa
ます。結果は、ブロックの最後の式です。他の通常の割り当てと同じように、/の終了後 に割り当てを使用します。let
run
まず、提供されたSwiftイディオムのセマンティクスを確実に理解してみましょう。
if let a = <expr> {
// then-block
}
else {
// else-block
}
これは、「<expr>
結果が非nilオプションになる場合は、then
ラップa
されていない値にバインドされたシンボルを使用して-blockを入力します。それ以外の場合は、else
ブロックを入力します。
特にノートa
バインドされている範囲内のみthen
-block。Kotlinでは、これを呼び出すことで簡単にこれを取得できます
<expr>?.also { a ->
// then-block
}
次のelse
ように-block を追加できます。
<expr>?.also { a ->
// then-block
} ?: run {
// else-block
}
これは、Swiftイディオムと同じセマンティクスになります。
私の答えは完全に他の人からの模倣猫です。しかし、私は彼らの表現を簡単に理解することができません。ですから、もっとわかりやすい答えを出せたらいいと思います。
迅速に:
if let a = b.val {
//use "a" as unwrapped
}
else {
}
コトリンでは:
b.val?.let{a ->
//use "a" as unwrapped
} ?: run{
//else case
}
let
代わりにを使用also
すると、run
ブロックがをlet
返すたびにブロックが実行されますnull
。
Swiftとは異なり、Kotlinで使用する前にオプションを展開する必要はありません。値がnullでないかどうかを確認するだけで、コンパイラーは実行したチェックに関する情報を追跡し、アンラップとして使用できるようにします。
Swiftの場合:
if let a = b.val {
//use "a" as unwrapped
} else {
}
コトリンでは:
if b.val != null {
//use "b.val" as unwrapped
} else {
}
ドキュメントを参照:(null-safety)そのような使用例
if let
ステートメント。SwiftのOptional Binding
(いわゆるif-let
ステートメント)を使用して、オプションに値が含まれているかどうかを調べ、含まれている場合は、その値を一時的な定数または変数として使用できるようにします。したがって、Optional Binding
for if-let
ステートメントは次のようになります。
スウィフトの
if-let
声明:
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
Kotlinでは、Swiftのように、予期しないnull値へのアクセスの試行によって引き起こされるクラッシュを回避するためにb.let { }
、適切にアンラップするために特定の構文(2番目の例のような)が提供されていますnullable types
。
Swiftの
if-let
声明のKotlin相当1:
val b: Int? = null
val a = b
if (a != null) {
println("Good news!")
} else {
println("Equal to 'null' or not set")
}
/* RESULT: Equal to 'null' or not set */
Kotlinのlet
関数をsafe-call演算子と組み合わせて使用すると、?:
null許容式を簡単に処理できます。
SwiftのステートメントのKotlin相当2 (インラインlet関数とElvisオペレーター)
if-let
:
val b: Int? = null
val a = b.let { nonNullable -> nonNullable } ?: "Equal to 'null' or not set"
println(a)
/* RESULT: Equal to 'null' or not set */
guard let
ステートメント。guard-let
Swiftのステートメントはシンプルで強力です。それはいくつかの条件をチェックし、それがfalseと評価された場合、else
ステートメントが実行され、通常はメソッドを終了します。
Swiftの
guard-let
発言を見てみましょう。
let b: Int? = nil
func testIt() {
guard let a = b else {
print("Equal to 'nil' or not set")
return
}
print("Good news!")
}
testIt()
/* RESULT: Equal to 'nil' or not set */
KotlinによるSwiftの
guard-let
発言の同様の効果:
Swiftとは異なり、Kotlinではガードステートメントはまったくありません。ただし、Elvis Operator
- ?:
を使用して同様の効果を得ることができます。
val b: Int? = 50
fun testIt() {
val a = b ?: return println("Equal to 'null' or not set")
return println("Good news!")
}
testIt()
/* RESULT: Good news! */
お役に立てれば。
name
がnullでない場合にのみコードを実行する方法は次のとおりです。
var name: String? = null
name?.let { nameUnwrapp ->
println(nameUnwrapp) // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
println(nameUnwrapp) // printed "Alex"
}
let
しているのかわかっていると思いますが、問題は、呼び出さelse
れたオブジェクトがの場合に実行される戦略についてlet
ですnull
。Swiftには、より自然な(議論の余地がある)方法があります。しかし、KotlinとSwiftの両方を何度も実行したので、SwiftのようにKotlinが簡単にアンラップできることを願っています。
これが私の変種です。非常に一般的な「nullでない場合」のケースに限定されています。
まず、これをどこかに定義します。
inline fun <T> ifNotNull(obj: T?, block: (T) -> Unit) {
if (obj != null) {
block(obj)
}
}
たぶん internal
競合を避けるため、。
次に、このSwiftコードを変換します。
if let item = obj.item {
doSomething(item)
}
このKotlinコードに:
ifNotNull(obj.item) { item ->
doSomething(item)
}
Kotlinのブロックでは常にそうであるように、引数を削除して使用できますit
。
ifNotNull(obj.item) {
doSomething(it)
}
ただし、ブロックが1〜2行を超える場合は、明示することをお勧めします。
これは、私が見つけたSwiftに似ています。
Swiftのスタイルのif-letを達成するためにkotlinにも同様の方法があります
if (val a = b) {
a.doFirst()
a.doSecond()
}
複数のnull許容値を割り当てることもできます
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
この種類のアプローチは、null許容値が1回以上使用される場合により適しています。私の意見では、null許容値は1回だけチェックされるため、パフォーマンスの面で役立ちます。
コメントには大きすぎるため、受け入れられた回答を明確にするためにこの回答を追加します。
ここでの一般的なパターンは、次のようにエルビス演算子で区切られたKotlinで使用可能なスコープ関数の任意の組み合わせを使用できるということです。
<nullable>?.<scope function> {
// code if not null
} :? <scope function> {
// code if null
}
例えば:
val gradedStudent = student?.apply {
grade = newGrade
} :? with(newGrade) {
Student().apply { grade = newGrade }
}
a
内部にアクセスしlet
てrun
ブロックすることはできません。