Kotlin의 Swift if let 문


123

Kotlin에는 아래 Swift 코드에 해당하는 것이 있습니까?

if let a = b.val {

}
else {

}

답변:


255

다음 let과 같이 -function을 사용할 수 있습니다 .

val a = b?.let {
    // If b is not null.
} ?: run {
    // If b is null.
}

run코드 블록이 필요한 경우에만 함수 를 호출 해야합니다. runelvis-operator ( ?:) 뒤에 oneliner 만있는 경우 -block을 제거 할 수 있습니다 .

주의하십시오 run블록이 경우 중 평가됩니다 bnull의 경우, 또는 경우 let- 블록들을 평가에 null.

이 때문에 일반적으로 if표현을 원합니다 .

val a = if (b == null) {
    // ...
} else {
    // ...
}

이 경우 else-block은 bnull이 아닌 경우에만 평가됩니다 .


41
동등하지 않습니다. a내부 letrun차단에 액세스 할 수 없습니다 .
재키 최

6
a아직 let및 범위 내에 정의되지 않았습니다 run. 그러나 암시 적 매개 변수를 사용하여 b내부 값에 액세스 할 수 있습니다 . 이것은 내가 생각하는 것과 같은 목적을 제공합니다. letit
marstran

1
신속한 코드는 a해당 코드 블록 이전에 할당을 완료합니다 . 그리고 a내부에 액세스 할 수 있습니다.
재키 최

1
무엇을 할당 a합니까? 그것의 경우 b, 다음 it동일한 목적을 제공합니다. -block a의 결과로 재 할당됩니까 val?
marstran

3
블록 it내 에서만 액세스 할 수 있습니다 let. let또는 run블록 의 결과 가에 할당됩니다 a. 결과는 블록의 마지막 표현식입니다. 다른 일반 할당과 마찬가지로 / 완료 후에 할당 사용합니다 . letrun
marstran

51

먼저 제공된 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 관용구와 동일한 의미가 생성됩니다.


11

내 대답은 완전히 다른 사람들의 모방 고양이입니다. 그러나 나는 그들의 표현을 쉽게 이해할 수 없다. 그래서 더 이해하기 쉬운 답변을 제공하는 것이 좋을 것 같습니다.

신속하게 :

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하지 않습니다, 우리가 원하는 것을.
Marko Topolnik 19 년

6

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)


이것은 b가 지역 변수 인 경우에만 작동합니다. 클래스 변수는 어떻습니까?
Warpzit

5

if let 성명서.

Swift Optional Binding(소위 if-let서술문)는 옵 셔널이 값을 포함하는지 여부를 알아 내고 만약 그렇다면 그 값을 임시 상수 또는 변수로 사용할 수 있도록하는 데 사용됩니다. 따라서 Optional Bindingfor 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-letSwift의 문장은 간단하고 강력합니다. 일부 조건을 확인하고 거짓으로 평가되면 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!  */

도움이 되었기를 바랍니다.


4

namenull이 아닐 때만 코드를 실행하는 방법은 다음과 같습니다 .

var name: String? = null
name?.let { nameUnwrapp ->
    println(nameUnwrapp)  // not printed because name was null
}
name = "Alex"
name?.let { nameUnwrapp ->
    println(nameUnwrapp)  // printed "Alex"
}

name == {}의 null 코드 인 경우, name이 String 인 경우 실행되지 않음-code execute : nameUnwrapp == name.
Александр Яковенко

1
나는 이것이 OP가 요구하는 것이라고 생각하지 않는다. 나는 OP가 이미 무엇을하는지 알고 있다고 확신 let하지만, 질문 은 호출 else되는 객체가 인 경우 실행 되는 전략에 관한 let것입니다 null. Swift는 더 자연스러운 (논쟁의 여지가있는) 방식으로 있습니다. 그러나 Kotlin과 Swift를 많이 수행 했으므로 Kotlin이 Swift처럼 간단한 언 래핑을 수행했으면합니다.
kalehv

2

다음은 매우 일반적인 "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 줄 이상이면 명시하는 것이 가장 좋습니다.

이것은 내가 찾을 수있는 스위프트와 비슷합니다.


0

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 토론


1
당신이 보여주는 접근 방식은 현재 컴파일되지 않는다는 점에 유의하십시오. 이 문제를 처리하기 위해 Kotlin 언어를 변경하는 방법에 대한 제안 일뿐입니다. 따라서 이것은 유효한 해결책이 아닙니다.
Peter F

0

댓글이 너무 커서 허용 된 답변을 명확히하기 위해이 답변을 추가하고 있습니다.

여기서 일반적인 패턴은 다음 과 같이 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 }
}

-1

내 생각에 가장 깨끗한 옵션은

빠른:

if let a = b.val {

} else {

}

Kotlin

b.val.also { a ->

} ?: run {

}

-1

Kotlin의 Swift if let 문

짧은 대답은 간단한 IF-ELSE 를 사용 하는 것입니다.이 주석의 당시 Kotlin LET에는 이에 상응하는 항목이 없습니다.

    if(A.isNull()){
// A is null
    }else{
// A is not null
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.