답변:
코 틀린에서 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
.
코 틀린, 많은 제어문을 포함 if
, when
또는 심지어 try
로 사용할 수 있습니다 표현 . 이것은 변수에 할당되고 함수 등에서 반환되는 결과를 가질 수 있음을 의미합니다.
Kotlin의 표현의 결과로 언어 에는 실제로 삼항 연산자가 필요하지 않습니다 .
if (a) b else c
삼항 연산자 식 대신 사용할 수 있습니다 a ? b : c
.
아이디어는 모든 사람들이 무엇을 알고 있기 때문에 이전 표현이 더 읽기 쉽다고 생각 ifelse
하지만 ? :
이미 구문에 익숙하지 않으면 다소 명확하지 않습니다.
그럼에도 불구하고 나는 종종 더 편리한 삼항 연산자를 그리워 한다는 것을 인정해야 합니다.
다른 대안들
언제
when
조건을 확인할 때 Kotlin에서 사용 된 구문 을 볼 수도 있습니다 . 또 다른 방법으로 if-else 캐스케이드를 표현하는 방법이기도합니다. 다음은 OTs 예에 해당합니다.
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
첫 번째는 object가 null과 같은 경우 제공된 기본값을 반환합니다. 두 번째는 같은 경우에 람다로 제공된 표현을 평가합니다.
용법:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
개인적으로 if
건설 인라인 보다 더 읽기 쉬운 코드
e.getMessage() ?: "unknown"
. 두 번째는 다음과 같이 표현 될 수 있습니다.obj?.lastMessage?.timestamp ?: { Date() }()
삼항 연산자와 동등한 Java
a ? b : c
한 줄로 Kotlin에서 간단한 IF
if(a) b else c
이 역할에서 보통의 경우 잘 작동하기 때문에 삼항 연산자가 없습니다 (조건? 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
Kotlin에서는
if
표현식입니다. 즉, 값을 반환합니다. 따라서(condition ? then : else)
평범한 경우이 역할에서 잘 작동하기 때문에 삼항 연산자가 없습니다 . 여기에서 수동 소스
// 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
다른 답변에 언급되지 않은 일부 코너 사례.
외관 때문에 takeIf 에서 코 틀린 1.1 삼원 연산자 a ? b : c
도 다음과 같이 표현 될 수있다 :
b.takeIf { a } ?: c
c가 null
다음 과 같은 경우에 더 짧아집니다 .
b.takeIf { a }
같은 또한 자바 세계 널 (null) 검사에서 그 전형적인주의 value != null ? value : defaultValue
단지에 ideomatic 코 틀린에 번역 value ?: defaultValue
.
유사는 a != null ? b : c
에 번역 할 수 있습니다 a?.let { b } ?: c
.
b.takeIf { a } ?: c
보다 짧고 읽기 쉬운 방법은 if (a) b else c
무엇입니까? 변수 이름과 조건이 길어질 수 있고 나쁜 줄을 나눌 수 있기 때문에 Terneray 연산자는 확실히 Kotlin에서 누락 된 기능입니다.
takeIf
항상 실제 사례 (여기 a
)를 평가 한다는 점에 유의해야합니다 . a
허위 일 경우 해당 표현을 쓸모 없게 계산할 수있을뿐만 아니라 , 스마트 캐스트에서 혜택을 누릴 수 없습니다 if (a is Int) { a + 3 }
.
{ a }
게으르게 평가 된 람다입니다.
b
" (여기서는 ) 여야합니다 . 그러나 { a }
게으른 상태 에서도 식의 결과를 결정하기 위해 평가 해야합니다 .
임무 :
다음 예제를 살펴 보겠습니다.
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
는 표현이 아닌 진술로되어 있습니다. 삼항 조건식과 더 관련있는 비교는 각 분기가 값을 반환하도록하여식이 값으로 평가 될 때 전체가 삼항 조건부에서 발생하는 것처럼 전체 값을 반환하도록하는 것입니다.
코 틀린에는 삼항 연산자가 없습니다. 언뜻보기에는 문제가있는 것 같습니다. 그러나 여기에 표현이 있기 때문에 다른 문장이라면 인라인으로 할 수 있다고 생각하십시오. 간단히 우리는해야합니다-
var number = if(n>0) "Positive" else "Negetive"
여기서 필요한만큼 블록을 차단할 수 있습니다. 처럼-
var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"
따라서이 줄은 삼항 연산자보다 간단하고 읽기 쉽습니다. 우리가 자바에서 둘 이상의 삼항 연산자를 사용할 때 그것은 끔찍한 것 같습니다. 그러나 여기에는 명확한 구문이 있습니다. 심지어 여러 줄로도 쓸 수 있습니다.
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"
또 다른 흥미로운 접근법은 다음을 사용하는 것입니다 when
.
when(a) {
true -> b
false -> b
}
좀 더 복잡한 시나리오에서 매우 유용 할 수 있습니다. 그리고 솔직히, 그것은 나보다 더 읽기 쉽습니다.if ... else ...
코 틀린에서 여러 가지 방법으로 할 수 있습니다
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에는 삼항 연산이 없지만 그 문제를 해결할 수있는 재미있는 방법이 있습니다. 다른 사람들이 지적했듯이 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은 코드 표현 방식에 많은 유연성을 제공합니다. 내 예제에는 수많은 변형이 있으며 아마도 아직까지도 발견하지 못한 방법이 있습니다. 이게 도움이 되길 바란다!
takeIf
내가 가장 좋아하는 옵션은 정말 우아합니다.
기억 삼항 연산자 와 엘비스 운영자 에 보류 별도의 의미 코 틀린를 많은 대중적인 언어와는 달리. 수행 expression? value1: value2
에 의해 당신에게 나쁜 말을 줄 것 코 틀린에 없기 때문에 다른 언어와는 달리, 컴파일러 코 틀린에는 삼항 연산자 에 언급 된 공식 문서가 . 그 이유는 if, when 및 try-catch 문 자체가 값을 반환하기 때문입니다.
따라서 수행 expression? value1: value2
은 다음으로 대체 될 수 있습니다.
val max = if (a> b) print ( "Choose a") else print ( "Choose b")
엘비스 운영자 것을 코 틀린이 있습니다 만 널 (NULL) 변수 전직의 경우에 작동합니다 :
내가 value1 이 null이면 다음 과 같은 것을
value3 = value1 ?: value2
하면 value2 가 반환되고 그렇지 않으면 value1 이 반환됩니다.
이 답변을 통해보다 명확한 이해를 얻을 수 있습니다 .
표준 표기법을 사용하지 않을 경우 다음과 같은 접두사 를 사용하여 표준 표기법을 작성 / 시뮬레이션 할 수도 있습니다 .
목표와 결과를 담을 클래스를 만듭니다.
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 / type 선언과 모순된다고 생각 합니다. 그것과 별개로 나는 어떤 이유도 보지 못한다. 인라인 if-else 조건 검사가 있다면 누군가가 분명히 몇 가지 생각을했을 것이라고 생각합니다. 다음 버전에서 기다려 보자.
다음과 같은 infix 함수를 사용하면 많은 일반적인 사용 사례를 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에는 삼항 연산자가 없으며 가장 닫힌 것은 다음 두 경우입니다.
val a = true if(a) print("A is true") else print("A is false")
? :의 왼쪽에있는 표현식이 널이 아닌 경우 elvis 연산자는이를 리턴하고 그렇지 않으면 표현식을 오른쪽에 리턴합니다. 오른쪽 표현식은 왼쪽이 널인 경우에만 평가됩니다.
val name = node.getName() ?: throw IllegalArgumentException("name expected")
예 : var energy : Int = data? .get (position) ?. energy? .toInt ()? : 0
kotlin에서 ? 를 사용하는 경우 문이 null을 반환하고 ? : 0을 반환하는 것처럼 작동 합니다.
Kotlin에서는 다음과 같이 삼항 연산을 사용할 수 있습니다. val x = if(a) "add b" else "add c"
다른 아이디어를 연구 한 후 다음과 같은 삼항 연산자를 도출했습니다.
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")
}
}
이 버전은 유창하며 널 병합 연산자와 충돌하지 않습니다.
then
대신 이름이 지정된 deviant의 답변과 동일 yes
합니다.