답변:
다음 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
또는 run
블록 의 결과 가에 할당됩니다 a
. 결과는 블록의 마지막 표현식입니다. 다른 일반 할당과 마찬가지로 / 완료 후에 할당 을 사용합니다 . let
run
먼저 제공된 Swift 관용구의 의미를 이해했는지 확인하겠습니다.
if let a = <expr> {
// then-block
}
else {
// else-block
}
의미 : " <expr>
결과가 nil이 아닌 선택 사항 인 경우 래핑되지 않은 값에 바인딩 된 then
기호와 함께 -block을 a
입력하고 그렇지 않으면 else
블록을 입력합니다 .
특히 -block 내에서만a
바인딩 됩니다then
. 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 {
}
Kotlin에서 :
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 {
}
Kotlin에서 :
if b.val != null {
//use "b.val" as unwrapped
} else {
}
더 많은 사용 사례는 문서를 참조하십시오 : (null-safety)
if let
성명서.Swift Optional Binding
(소위 if-let
서술문)는 옵 셔널이 값을 포함하는지 여부를 알아 내고 만약 그렇다면 그 값을 임시 상수 또는 변수로 사용할 수 있도록하는 데 사용됩니다. 따라서 Optional Binding
for if-let
문은 다음과 같습니다.
Swift의
if-let
진술 :
let b: Int? = 50
if let a = b {
print("Good news!")
} else {
print("Equal to 'nil' or not set")
}
/* RESULT: Good news! */
Swift와 마찬가지로 Kotlin에서는 예상하지 않은 경우 null 값에 액세스하려고 할 때 발생하는 충돌을 방지하기 위해 b.let { }
적절한 래핑 해제를 위해 특정 구문 (예 : 두 번째 예)이 제공됩니다 nullable types
.
Kotlin 은 Swift의
if-let
진술 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
함수를 안전 호출 연산자와 함께 사용하면 ?:
nullable 표현식을 간결하게 처리 할 수 있습니다.
Swift의 선언문 의 Kotlin에 해당하는 2 (Inline 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의 문장은 간단하고 강력합니다. 일부 조건을 확인하고 거짓으로 평가되면 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를 많이 수행 했으므로 Kotlin이 Swift처럼 간단한 언 래핑을 수행했으면합니다.
다음은 매우 일반적인 "if not 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 줄 이상이면 명시하는 것이 가장 좋습니다.
이것은 내가 찾을 수있는 스위프트와 비슷합니다.
kotlin에서 Swift의 스타일을 달성하는 비슷한 방법이 있습니다.
if (val a = b) {
a.doFirst()
a.doSecond()
}
여러 nullable 값을 할당 할 수도 있습니다.
if (val name = nullableName, val age = nullableAge) {
doSomething(name, age)
}
이러한 종류의 접근 방식은 nullable 값이 1 회 이상 사용되는 경우 더 적합합니다. 제 생각에는 nullable 값이 한 번만 확인되기 때문에 성능 측면에서 도움이됩니다.
출처 : Kotlin 토론
댓글이 너무 커서 허용 된 답변을 명확히하기 위해이 답변을 추가하고 있습니다.
여기서 일반적인 패턴은 다음 과 같이 Elvis 연산자로 구분 된 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
차단에 액세스 할 수 없습니다 .