कोटलिन में इस अभिव्यक्ति के बराबर क्या है?
a ? b : c
यह कोटलिन में मान्य कोड नहीं है।
कोटलिन में इस अभिव्यक्ति के बराबर क्या है?
a ? b : c
यह कोटलिन में मान्य कोड नहीं है।
जवाबों:
कोटलिन में, if
कथन अभिव्यक्ति हैं। तो निम्नलिखित कोड समतुल्य है:
if (a) b else c
अभिव्यक्ति और कथन के बीच का अंतर यहाँ महत्वपूर्ण है। जावा / सी # / जावास्क्रिप्ट में, 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")
अद्यतन: लेकिन कुछ और जावा-जैसे सशर्त स्विच करने के लिए आपको कुछ इस तरह की आवश्यकता होगी
infix fun <T> Boolean.then(param: () -> T): T? = if (this) param() else null
println(condition then { "yes" } ?: "no")
लंबोदर पर ध्यान दें। अपनी सामग्री गणना जब तक हम बनाने के लिए स्थगित कर दिया जाना चाहिए यकीन condition
हैtrue
यह एक अनाड़ी दिखता है, यही कारण है कि जावा टर्नरी ऑपरेटर को कोटलिन में पोर्ट करने के लिए उच्च मांग वाला अनुरोध मौजूद है
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
।
Kotlin में, कई नियंत्रण विवरण सहित if
, when
या यहाँ तक कि try
के रूप में इस्तेमाल किया जा सकता भाव । इसका मतलब यह है कि उन लोगों के पास एक परिणाम हो सकता है जो एक चर को सौंपा जा सकता है, एक समारोह से वापस आ सकता है आदि।
कोटलिन के भावों के परिणामस्वरूप, भाषा को वास्तव में टर्नरी ऑपरेटर की आवश्यकता नहीं है ।
if (a) b else c
टर्नरी ऑपरेटर अभिव्यक्ति के बजाय आप क्या उपयोग कर सकते हैं a ? b : c
।
मुझे लगता है कि विचार यह है कि पूर्व अभिव्यक्ति अधिक पठनीय है क्योंकि हर कोई जानता है कि क्या ifelse
करता है, जबकि ? :
यह स्पष्ट नहीं है कि आप पहले से ही वाक्य रचना से परिचित नहीं हैं।
फिर भी, मुझे यह स्वीकार करना होगा कि मैं अक्सर अधिक सुविधाजनक टर्नरी ऑपरेटर को याद करता हूं ।
अन्य विकल्प
कब
when
शर्तों की जाँच होने पर आप कोटलिन में उपयोग किए गए निर्माण भी देख सकते हैं। यह व्यक्त करने का एक तरीका भी है-यदि वैकल्पिक तरीके से कैस्केड किया जाए। निम्नलिखित ओटी उदाहरण के अनुरूप है।
when(a) {
true -> b
false -> c
}
एक्सटेंशन
अन्य उत्तर शो में कई अच्छे उदाहरणों ( कोटलिन टर्नेरी कंडिशनल ऑपरेटर ) के रूप में, एक्सटेंशन आपके उपयोग के मामले को सुलझाने में भी मदद कर सकते हैं।
अपने लिए मैं निम्नलिखित विस्तार कार्यों का उपयोग करता हूं:
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
यदि वस्तु ऑब्जेक्ट के बराबर है तो पहले वाला डिफ़ॉल्ट मान लौटा देगा। दूसरा एक ही मामले में लैम्ब्डा में प्रदान की गई अभिव्यक्ति का मूल्यांकन करेगा।
उपयोग:
1) e?.getMessage().or("unknown")
2) obj?.lastMessage?.timestamp.or { Date() }
व्यक्तिगत रूप से मेरे लिए कोड अधिक if
निर्माण योग्य से अधिक पठनीय है
e.getMessage() ?: "unknown"
। दूसरे के रूप में व्यक्त किया जा सकता हैobj?.lastMessage?.timestamp ?: { Date() }()
जावा के टर्नरी ऑपरेटर के समकक्ष
a ? b : c
एक लाइन में एक सरल IF in Kotlin है
if(a) b else c
कोई टर्नरी ऑपरेटर नहीं है (स्थिति? फिर: और), क्योंकि साधारण अगर इस भूमिका में ठीक काम करता है।
https://kotlinlang.org/docs/reference/control-flow.html#if-expression
नल तुलना के लिए विशेष मामला
आप एल्विस ऑपरेटर का उपयोग कर सकते हैं
if ( a != null ) a else b
// equivalent to
a ?: b
नहीं है कोई त्रिगुट ऑपरेटर kotlin में, के रूप में if else
ब्लॉक रिटर्न मूल्य
तो, आप कर सकते हैं:
val max = if (a > b) a else b
जावा के बजायmax = (a > b) ? b : c
हम when
निर्माण का उपयोग भी कर सकते हैं , यह भी मूल्य लौटाता है:
val max = when(a > b) {
true -> a
false -> b
}
यहाँ कोटलिन प्रलेखन के लिए लिंक है: नियंत्रण प्रवाह: यदि, जब, के लिए, जबकि
कोटलिन में,
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
कुछ कोने के मामलों का अन्य उत्तरों में उल्लेख नहीं किया गया है।
Kotlin 1.1 में टेकआईएफ की उपस्थिति के बाद से टर्नरी ऑपरेटर a ? b : c
को भी इस तरह व्यक्त किया जा सकता है:
b.takeIf { a } ?: c
यह उस स्थिति में भी छोटा हो जाता है जब c null
:
b.takeIf { a }
यह भी ध्यान दें कि जावा दुनिया में विशिष्ट शून्य चेक value != null ? value : defaultValue
सिर्फ वैचारिक कोटलिन में अनुवाद की तरह है value ?: defaultValue
।
इसी तरह a != null ? b : c
का अनुवाद किया जा सकता है a?.let { b } ?: c
।
b.takeIf { a } ?: c
छोटा और अधिक पठनीय कैसे है if (a) b else c
? टरनेरे ऑपरेटर निश्चित रूप से कोटलिन में चर नाम से एक लापता विशेषता है और स्थिति लंबी हो सकती है और आपको उस रेखा को विभाजित कर सकती है जो खराब है
takeIf
हमेशा सही-मामले (यहां a
) का मूल्यांकन करता है । न केवल यह कि व्यर्थ होने पर अभिव्यक्ति की गणना बेकार की a
जा सकती है, लेकिन आप स्मार्ट कास्ट ला ला से लाभ नहीं उठा सकते हैं if (a is Int) { a + 3 }
।
{ a }
एक आलसी का मूल्यांकन किया हुआ लंबोदर है।
b
) का मूल्यांकन करना चाहिए "। लेकिन फिर भी { a }
, जबकि आलसी, अभिव्यक्ति का परिणाम निर्धारित करने के लिए मूल्यांकन किया जाना चाहिए।
जावा
int temp = a ? b : c;
कोटलिन के बराबर lin
var temp = if (a) b else c
TASK :
आइए निम्नलिखित उदाहरण पर विचार करें:
if (!answer.isSuccessful()) {
result = "wrong"
} else {
result = answer.body().string()
}
return result
हमें कोटलिन में निम्नलिखित समकक्ष की आवश्यकता है:
वापसी (उत्तर ।isSuccessful ())
?
"गलत":
उत्तर। कोई ()। स्ट्रिंग ()।
समाधान :
1. ए । आप if-expression
कोटलिन में उपयोग कर सकते हैं :
return if (!answer.isSuccessful()) "wrong" else answer.body().string()
1. बी । यह बहुत अच्छा हो सकता है यदि आप इसे फ्लिप करते हैं if-expression
(चलो इसके बिना करते हैं not
):
return if (answer.isSuccessful()) answer.body().string() else "wrong"
२ । कोटलिन का एल्विस ऑपरेटर ?:
बेहतर काम कर सकता है:
return answer.body()?.string() ?: "wrong"
३ । या Extension function
संबंधित Answer
वर्ग के लिए उपयोग करें :
fun Answer.bodyOrNull(): Body? = if (isSuccessful()) body() else null
४ । Extension function
आप का उपयोग करके एक कोड को कम कर सकते हैं धन्यवाद Elvis operator
:
return answer.bodyOrNull()?.string() ?: "wrong"
५ । या बस when
ऑपरेटर का उपयोग करें :
when (!answer.isSuccessful()) {
parseInt(str) -> result = "wrong"
else -> result = answer.body().string()
}
उम्मीद है की यह मदद करेगा।
जब सी-जैसी भाषाओं के स्विच ऑपरेटर की जगह लेता है। सबसे सरल रूप में यह ऐसा दिखता है
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"
तो यह रेखा टर्नरी ऑपरेटर की तुलना में इतनी सरल और बहुत पठनीय है। जब हम जावा में एक से अधिक टर्नरी ऑपरेटर का उपयोग करते हैं तो यह भयानक लगता है। लेकिन यहां हमारे पास एक स्पष्ट वाक्यविन्यास है। यहां तक कि हम इसे कई लाइन में भी लिख सकते हैं।
आप var a= if (a) b else c
टर्नरी ऑपरेटर के स्थान पर उपयोग कर सकते हैं ।
कोटलिन की एक और अच्छी अवधारणा एल्विस ऑपरेटर है। आपको हर बार नल की जांच करने की आवश्यकता नहीं है।
val l = b?.length ?: -1
यदि b null नहीं है तो यह लंबाई वापस आ जाएगी अन्यथा यह राइट साइड स्टेटमेंट निष्पादित करता है।
आकर्षित नोक के रूप में, अगर अभिव्यक्ति के रूप में कोटलिन का उपयोग किया जाता है, तो टर्नरी कंडिशनल ऑपरेटर अब जरूरी नहीं है,
लेकिन एक्सटेंशन फ़ंक्शन और इन्फिक्स ओवरलोडिंग के साथ, आप इसे स्वयं लागू कर सकते हैं, यहां एक उदाहरण है
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(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
कोटलिन में कोई टर्नरी ऑपरेशन नहीं है, लेकिन इसके आसपास काम करने के कुछ मजेदार तरीके हैं। जैसा कि अन्य ने बताया है, कोटलिन में एक सीधा अनुवाद इस तरह दिखेगा:
val x = if (condition) result1 else result2
लेकिन, व्यक्तिगत रूप से, मुझे लगता है कि थोड़ा अव्यवस्थित और पढ़ने में कठिन हो सकता है। पुस्तकालय में निर्मित कुछ अन्य विकल्प हैं। आप एक सहायक ऑपरेटर के साथ takeIf {} का उपयोग कर सकते हैं:
val x = result1.takeIf { condition } ?: result2
वहाँ क्या हो रहा है कि takeIf {} कमांड या तो आपका result1 या null देता है, और एल्विस ऑपरेटर null विकल्प को संभालता है। उदाहरण के लिए, कुछ अतिरिक्त विकल्प हैं, {{}
val x = result1.takeUnless { condition } ?: result2
भाषा स्पष्ट है, आप जानते हैं कि यह क्या कर रहा है।
यदि यह आमतौर पर इस्तेमाल की जाने वाली स्थिति है, तो आप कुछ मजेदार भी कर सकते हैं जैसे इनलाइन एक्सटेंशन विधि का उपयोग करें। चलो मान लेते हैं कि हम एक इंट के रूप में एक गेम स्कोर को ट्रैक करना चाहते हैं, उदाहरण के लिए, और हम हमेशा 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 }
जैसा कि आप देख सकते हैं, कोटलिन आपके कोड को व्यक्त करने के तरीके का चयन करने में बहुत अधिक लचीलापन प्रदान करता है। मेरे उदाहरणों के अनगिनत रूप हैं और संभवत: ऐसे तरीके जो मैंने अभी तक खोजे नहीं हैं। आशा है कि ये आपकी मदद करेगा!
takeIf
वास्तव में मेरा पसंदीदा विकल्प है, बहुत सुंदर।
याद रखें कि टर्नरी ऑपरेटर और एल्विस ऑपरेटर कई लोकप्रिय भाषाओं के विपरीत कोटलिन में अलग-अलग अर्थ रखते हैं। करना expression? value1: value2
आपको किसी अन्य भाषा के विपरीत, कोटलिन कंपाइलर द्वारा बुरे शब्द देगा, क्योंकि कोटलिन में कोई टर्नरी ऑपरेटर नहीं है जैसा कि आधिकारिक डॉक्स में उल्लेख किया गया है । कारण यह है कि यदि, कब और कब-कब-कब बयान स्वयं मान लौटाते हैं।
तो, करने expression? value1: value2
से प्रतिस्थापित किया जा सकता है
वैल अधिकतम = यदि (a> b) प्रिंट ("एक चुनें") और प्रिंट ("बी चुनें")
एल्विस ऑपरेटर कि Kotlin है, केवल नल चर पूर्व के मामले में काम करता है .:
मैं कुछ ऐसा करते हैं
value3 = value1 ?: value2
तो अगर मान 1 है अशक्त तो मान 2 लौटा दिया जाएगा अन्यथा मान 1 लौटा दिया जाएगा।
इन उत्तरों से अधिक स्पष्ट समझ हासिल की जा सकती है ।
आप इसके लिए if
कोटलिन में अभिव्यक्ति का उपयोग कर सकते हैं । कोटलिन if
में एक परिणाम मूल्य के साथ एक अभिव्यक्ति है। तो कोटलिन में हम लिख सकते हैं
fun max(a: Int, b: Int) = if (a > b) a else b
और जावा में हम समान लेकिन बड़े कोड के साथ प्राप्त कर सकते हैं
int max(int a, int b) {
return a > b ? a : b
}
यदि आप मानक संकेतन का उपयोग नहीं करते हैं तो आप infix का उपयोग करके इसे बना / अनुकरण भी कर सकते हैं कुछ इस तरह से :
अपना लक्ष्य रखने के लिए एक क्लास बनाएं और परिणाम:
data class Ternary<T>(val target: T, val result: Boolean)
एक ternary ऑपरेशन अनुकरण करने के लिए कुछ infix फ़ंक्शन बनाएं
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 ?: ""
यहाँ कोटलिन स्वयं शून्य मान की जाँच करता है और यदि यह अशक्त है तो यह रिक्त स्ट्रिंग मान से गुजरता है।
कोई इस तरह का उपयोग क्यों करेगा:
when(a) {
true -> b
false -> b
}
जब आप वास्तव में ऐसा कुछ उपयोग कर सकते हैं ( a
इस मामले में बूलियन है):
when {
a -> b
else -> b
}
? and :
एक प्रकार की जांच के बजाय अशक्त / प्रकार की घोषणा के साथ विरोधाभास है। इसके अलावा मुझे कोई कारण नहीं दिखता। मुझे लगता है कि किसी ने निश्चित रूप से कुछ विचार रखा होगा, अगर इनलाइन है तो-और शर्त की जांच करें। आइए इंतजार करें और भविष्य के संस्करणों में देखें।
आवेदन के साथ काम करते समय (), टर्नरी ऑपरेशन से निपटने के दौरान बहुत आसान लगता है, क्योंकि यह अधिक सुरुचिपूर्ण है और आपको कमरा देता है
val columns: List<String> = ...
val band = Band().apply {
name = columns[0]
album = columns[1]
year = columns[2].takeIf { it.isNotEmpty() }?.let { it.toInt() } ?: 0
}
निम्नलिखित कार्यों के साथ मैं कई सामान्य उपयोग के मामलों को कवर कर सकता हूं, ठीक उसी तरह जैसे कि पायथन में किया जा सकता है:
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
कोटलिन में कोई टर्नरी ऑपरेटर नहीं है, सबसे बंद दो मामलों के नीचे हैं,
val a = true if(a) print("A is true") else print("A is false")
यदि बाईं ओर अभिव्यक्ति ?: शून्य नहीं है, तो एल्विस ऑपरेटर इसे वापस कर देता है, अन्यथा यह अभिव्यक्ति को दाईं ओर लौटाता है। ध्यान दें कि दाएं-हाथ की अभिव्यक्ति का मूल्यांकन केवल तभी किया जाता है जब बाएं हाथ की ओर अशक्त हो।
val name = node.getName() ?: throw IllegalArgumentException("name expected")
उदाहरण: var energy: Int = data? .get (स्थिति) ?. energy? .toInt ()?: 0
यदि आप उपयोग कर रहे हैं तो कोटलिन में ?: यह ऐसे काम करेगा जैसे यदि स्टेटमेंट शून्य हो जाएगा ?: 0 इसमें 0 लगेगा या जो भी आपने इस पक्ष को लिखा है।
कोटलिन में आप इस तरह के टर्नरी ऑपरेशन का उपयोग कर सकते हैं: 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
इसके बजाय रखा गया है yes
।