Operator Warunkowy Kotlina Trójwarstwowa

Jaki jest odpowiednik tego wyrażenia w Kotlinie?

a ? b : c

To nie jest poprawny kod w Kotlinie.

Author: Drew Noakes, 2013-05-02

26 answers

W Kotlinie, if wyrażenia są wyrażeniami. Zatem następujący kod jest równoważny:

if (a) b else c

Rozróżnienie między wyrażeniem a stwierdzeniem jest tutaj ważne. W Javie/C#/JavaScript, if tworzy instrukcję, co oznacza, że nie rozwiązuje się do wartości. Bardziej konkretnie, nie można przypisać go do zmiennej.

// Valid Kotlin, but invalid Java/C#/JavaScript
var v = if (a) b else c

Jeśli pochodzisz z języka, w którym if jest stwierdzeniem, może to wydawać się nienaturalne, ale to uczucie powinno wkrótce ustąpić.

 382
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-31 15:33:08

Możesz zdefiniować własną funkcję rozszerzenia Boolean, która zwraca null, Gdy Boolean jest false, aby zapewnić strukturę podobną do operatora trójdzielnego:

infix fun <T> Boolean.then(param: T): T? = if (this) param else null

To sprawi, że wyrażenie a ? b : c przełoży się na a then b ?: c, Tak:

println(condition then "yes" ?: "no")

Aktualizacja: Ale aby zrobić więcej przełączników warunkowych podobnych do Javy, będziesz potrzebował czegoś takiego

infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null

println(condition then { "yes" } ?: "no") uważaj na lambdę. jego obliczenie zawartości powinno zostać przełożone do czasu upewnienia się, że condition jest true

Ten wygląda niezdarnie, dlatego istnieje wysokie żądanie, aby portować Java ternary operator do Kotlina

 48
Author: deviant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-05 20:42:36

Dla siebie używam następujących funkcji rozszerzenia:

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

Pierwszy zwróci podaną wartość domyślną, jeśli obiekt jest równy null. Drugi w tym samym przypadku oceni wyrażenie podane w lambda.

Użycie:

1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }

Osobiście dla mnie powyższy kod bardziej czytelny niż if Budowa inlining

 30
Author: ruX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 15:41:39

W Kotlinie if jest wyrażeniem, tzn. Zwraca wartość. Dlatego nie ma operatora trójdzielnego (condition ? then : else), ponieważ zwykłe, jeśli działa dobrze w tej roli. manual source from here

// 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
 24
Author: Kris Roofe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-24 05:30:11

W kotlinie nie ma operatora trójdzielnego , jako if else block Zwraca wartość

Więc możesz zrobić: val max = if (a > b) a else b zamiast Javy max = (a > b) ? b : c

Możemy również użyć when Budowa, zwraca również wartość:

val max = when(a > b) {
    true -> a
    false -> b
}

Oto link do dokumentacji Kotlina : przepływ sterowania: if, when, for, while

 24
Author: romiope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 09:55:25

Spójrz na docs :

W Kotlinie, if jest wyrażeniem, tzn. Zwraca wartość. Dlatego tam nie ma operatora trójdzielnego (warunek? następnie: else), ponieważ zwykłe, jeśli działa dobrze w tej roli.

 23
Author: Li Ying,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 11:39:46

Niektóre przypadki narożne nie wymienione w innych odpowiedziach.

Od wystąpienia takeIf w Kotlina 1.1 Operator trójkowy a ? b : c można również wyrazić następująco:

b.takeIf { a } ?: c

To staje się jeszcze krótsze w przypadku, gdy C jest null:

b.takeIf { a }

Zauważ również, że typowe w świecie Java sprawdzania null, takie jak value != null ? value : defaultValue tłumaczą w ideomatic Kotlin tylko value ?: defaultValue.

Podobne a != null ? b : c można przetłumaczyć na a?.let { b } ?: c.

 21
Author: Vadzim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 13:24:19

Kotlin ma wyrażenia

W Kotlinie wiele instrukcji kontrolnych, w tym if, when lub nawet try mogą być używane jako wyrażenia . Oznacza to, że mają wynik i mogą być przypisane do zmiennej, zwracane z funkcji itd.

Składniowo, nie ma potrzeby stosowania operatora trójdzielnego

Powiedziawszy to, Kotlin nie potrzebuje operatora trójdzielnego.

if (a) b else c jest tym, czego można użyć zamiast wyrażenia Java a ? b : c.

Myślę, że idea jest taka, że ten ostatni jest mniej czytelny, ponieważ każdy wie, co robi ifelse, podczas gdy ? : jest raczej niewygodne, jeśli nie jesteś zaznajomiony ze składnią. Chociaż muszę przyznać, że często brakuje mi wygodniejszego operatora trójdzielnego.

Inne Alternatywy

Kiedy

Możesz również zobaczyć wiele when konstrukcji, gdy warunki są sprawdzane w Kotlinie. Jest to również sposób wyrażania kaskad if-else w alternatywny sposób. Następujące odpowiedzi odpowiadają twoim przykład.

when(a) {
    true -> b
    false -> c
}

Rozszerzenia

Jak wiele dobrych przykładów (Kotlin Ternary Conditional Operator) w innych odpowiedziach pokazuje, rozszerzenia mogą być również dobrym rozwiązaniem.

 17
Author: s1m0nw1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-17 19:36:58

Java

int temp = a ? b : c;

Odpowiednik Kotlina:

var temp = if (a) b else c
 14
Author: doubleThunder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 10:59:01

Gdy zastępuje operator przełącznika języków C-podobnych. W najprostszej formie wygląda to tak

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> {
        print("x is neither 1 nor 2")
    }
}
 12
Author: Guruprasath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:21:38

W Kotlinie nie ma operatora trójdzielnego. Na pierwszy rzut oka wydaje się to problematyczne. Ale myślę, że możemy to zrobić z inline if else, ponieważ jest to wyrażenie tutaj. Po prostu musimy to zrobić -

var number = if(n>0) "Positive" else "Negetive"

Tutaj możemy inaczej, jeśli blokować zbyt wiele, ile potrzebujemy. Like -

var number = if(n>0) "Positive" else if(n<0) "Negative" else "Zero"

Więc ta linia jest tak prosta i dużo czytelna niż operator trójkowy. kiedy używamy więcej niż jednego operatora trójdzielnego w Javie, wydaje się to straszne. Ale tutaj mamy jasną składnię. nawet możemy to napisać w wielu wierszach też.

 11
Author: HM Nayem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 22:40:26

Jak zacytował Drew Noakes, kotlin używa polecenia if jako wyrażenia, Tak więc trójkowy Operator warunkowy nie jest już konieczny,

Ale z funkcją rozszerzenia i przeciążeniem infiksu, możesz zaimplementować to samodzielnie, oto przykład

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
}

Następnie użyj go w ten sposób

val grade = 90
val clazz = (grade > 80) then "A" or "B"
 7
Author: Minami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-07 09:20:32

Innym ciekawym podejściem byłoby użycie when:

when(a) {
  true -> b
  false -> b
}

Może być bardzo przydatny w niektórych bardziej złożonych scenariuszach. I szczerze mówiąc, jest dla mnie bardziej czytelny niż if ... else ...

 6
Author: Grzegorz Piwowarek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 20:51:54

Możesz to zrobić wiele sposobów w Kotlinie

  1. Using if

    if(a) b else c
    
  2. Użycie kiedy

    when (a) { 
        true -> print("value b") 
        false -> print("value c") 
        else -> {  
            print("default return in any other case") 
        } 
    }
    
  3. Null Safety

    val a = b ?: c
    
 6
Author: Rajesh Dalsaniya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-06 11:00:28

W Kotlinie nie ma operatora trójdzielnego, gdyż istnieje wyrażenie if:

var d = if (a) b else c
 5
Author: dey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-27 14:24:45

Zgodnie z dokumentacją Kotlina używam następującego kodu:

 val max = if (a > b) a else b

I:

when (x) {
  1 -> print("x == 1")
  2 -> print("x == 2")
  else -> { // Note the block
      print("x is neither 1 nor 2")
  }
}

Jeśli chcesz wiedzieć więcej informacji sprawdź ten link: przepływ sterowania: if, when, for, while

 4
Author: Ranjith Rayapati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 09:52:58

Możesz użyć do tego wyrażenia if w Kotlinie. W Kotlinie if jest wyrażeniem o wartości wynikowej. Więc w Kotlinie możemy napisać

fun max(a: Int, b: Int) = if (a > b) a else b

I w Javie możemy osiągnąć to samo, ale z większym kodem

int max(int a, int b) {
return a > b ? a : b
}
 3
Author: Gulzar Bhat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-06 09:41:22

W Kotlinie nie ma operacji trójwarstwowej, ale jest kilka fajnych sposobów na obejście tego. Jak zauważyli inni, bezpośrednie tłumaczenie na język Kotlin wyglądałoby tak:

val x = if (condition) result1 else result2
Ale, osobiście, myślę, że może być trochę bałagan i trudne do odczytania. Istnieje kilka innych opcji wbudowanych w bibliotece. Możesz użyć takeIf {} z operatorem elvis:
val x = result1.takeIf { condition } ?: result2

Dzieje się tak, że polecenie takeIf {} zwraca albo wynik1 albo null, A operator obsługuje opcję null. Istnieje kilka dodatkowych opcji, takeUnless {}, na przykład:

val x = result1.takeUnless { condition } ?: result2

Język jest jasny, wiesz, co to robi.

Jeśli jest to powszechnie używany warunek, możesz również zrobić coś fajnego, na przykład użyć metody rozszerzenia w linii. Załóżmy, że chcemy śledzić wynik gry jako Int, na przykład, i chcemy zawsze zwracać 0, jeśli dany warunek nie jest spełniony:

inline fun Int.zeroIfFalse(func: () -> Boolean) : Int = if (!func.invoke()) 0 else this     
Ok, to wygląda brzydko. Ale zastanów się, jak to wygląda, gdy jest użyte:
var score = 0
val twoPointer = 2
val threePointer = 3

score += twoPointer.zeroIfFalse { scoreCondition } 
score += threePointer.zeroIfFalse { scoreCondition } 

Jak widzisz, Kotlin oferuje dużą elastyczność w sposobie wyrażania kodu. Istnieje niezliczona ilość odmian moich przykładów i prawdopodobnie sposobów, których jeszcze nie odkryłem. Mam nadzieję, że to pomoże!

 3
Author: pranalli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-04 21:06:04

Kolejne krótkie podejście do użycia

val value : String = "Kotlin"

value ?: ""

Tutaj sam kotlin sprawdza wartość null i jeśli jest null, to przekazuje pustą wartość łańcuchową.

 2
Author: Vinod Pattanshetti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-22 09:32:12

Po co używać czegoś takiego:

when(a) {
  true -> b
  false -> b
}

Kiedy możesz użyć czegoś takiego (a jest boolean w tym przypadku):

when {
  a -> b
  else -> b
}
 2
Author: ZZ 5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 11:40:49

W Kotlinie nie ma operatora trójdzielnego .

W Kotlinie, if jest wyrażeniem, tzn. Zwraca wartość.

Dlatego nie ma operatora trójdzielnego (warunek ? następnie: else), ponieważ zwykłe, jeśli działa dobrze w tej roli.

Odpowiednik w Kotlinie

var a = if (a) b else c

Dokument referencyjny: przepływ sterowania: if, when, for, while

 1
Author: Gowtham Subramaniam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 07:15:22

Dzięki następującym funkcjom infiksowym mogę objąć wiele typowych przypadków użycia w podobny sposób, jak można to zrobić w Pythonie:

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
 0
Author: Nicolas Cornette,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-23 09:46:57

Użyj instrukcji warunkowej if-else lub operatora when w następujący sposób

when(a) {
  true -> b
  false -> b
}
 0
Author: cleaning agent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-06 03:05:49

W Kotlinie nie ma operatora trójdzielnego, najbardziej zamknięte są poniższe dwa przypadki,

  • If else as expression

val a = true if(a) print("A is true") else print("A is false")

  • operator Elvisa

Jeśli wyrażenie na lewo od ?: nie jest null, operator Elvisa zwraca je, w przeciwnym razie zwraca wyrażenie po prawej stronie. Uwaga że wyrażenie po prawej stronie jest obliczane tylko wtedy, gdy po lewej strona jest zerowa.

 val name = node.getName() ?: throw IllegalArgumentException("name expected")

Bibliografia docs

 0
Author: JTeam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-02 10:58:51

Przykład: var energy: Int = data?.get (pozycja)?.energia?.toInt ()?: 0

W kotlinie jeśli używasz ?: {[3] } to będzie działać jak jeśli instrukcja zwróci null wtedy ?: 0 zajmie to 0 lub cokolwiek masz napisać na tej stronie.

 0
Author: abhilasha Yadav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-19 06:38:58

Podczas pracy z apply(), let wydaje się bardzo przydatne w przypadku operacji trójkowych, ponieważ jest bardziej eleganckie i daje Ci miejsce

val columns: List<String> = ...
val band = Band().apply {
    name = columns[0]
    album = columns[1]
    year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
 0
Author: Juan Mendez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-10 10:03:34