कोटलिन में जांच करने का सबसे अच्छा तरीका है?


96

क्या मुझे डबल =, या ट्रिपल का उपयोग करना चाहिए =?

if(a === null)  {
//do something
}

या

if(a == null)  {
//do something
}

इसी तरह 'बराबर नहीं' के लिए:

if(a !== null)  {
//do something
}

या

if(a != null)  {
//do something
}

1
लिंक पर देखें: - kotlinlang.org/docs/reference/null-safety.html .............. कोटलिन डॉक्स में यह आसान है
sushildlh

जवाबों:


62

दोनों दृष्टिकोण समान बायोटेक उत्पन्न करते हैं ताकि आप जो चाहें चुन सकें।


4
अगर मैं इसे सही तरीके से समझ गया तो वह कोटलिन में नल की जांच करने का सबसे अच्छा तरीका पूछ रहा है, न कि कौन सा दृष्टिकोण सबसे अच्छा बाइट-कोड उत्पन्न करता है। @ बेनिटोर्टोली उत्तर आशाजनक लग रहा है, यह बॉयलरप्लेट कोड को कम कर देता है
12

155

एक संरचनात्मक समानता a == bका अनुवाद किया जाता है

a?.equals(b) ?: (b === null)

इसलिए जब तुलना की जाती है null, तो संरचनात्मक समानता a == nullको संदर्भित समानता से अनुवादित किया जाता है a === null

डॉक्स के अनुसार , आपके कोड को अनुकूलित करने का कोई मतलब नहीं है, इसलिए आप इसका उपयोग कर सकते हैं a == nullऔर a != null


ध्यान दें कि यदि चर एक परिवर्तनशील संपत्ति है, तो आप इसे इसके गैर-अशक्त प्रकार में स्मार्ट कास्ट नहीं कर पाएंगे।if बयान के (क्योंकि मान किसी अन्य थ्रेड द्वारा संशोधित किया गया हो सकता है) और आपको letइसके बजाय सुरक्षित कॉल ऑपरेटर का उपयोग करना होगा ।

सुरक्षित कॉल ऑपरेटर ?.

a?.let {
   // not null do something
   println(it)
   println("not null")
}


आप इसे एल्विस ऑपरेटर के साथ संयोजन में उपयोग कर सकते हैं।

एल्विस ऑपरेटर ?: (मैं अनुमान लगा रहा हूं क्योंकि पूछताछ का निशान एल्विस के बालों की तरह दिखता है)

a ?: println("null")

और अगर आप कोड का एक ब्लॉक चलाना चाहते हैं

a ?: run {
    println("null")
    println("The King has left the building")
}

दोनों को मिलाना

a?.let {
   println("not null")
   println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
    println("null")
    println("When things go null, don't go with them")
}

1
आप ifअशक्त जांच के लिए उपयोग क्यों नहीं करते ? a?.let{} ?: run{}केवल दुर्लभ मामलों में ही उचित है, अन्यथा यह मुहावरेदार नहीं है
वोड्डन

2
@voddan मैं सुझाव नहीं दे रहा था कि यदि nullचेक के लिए उपयोग नहीं किया गया है, तो मैं अन्य व्यवहार्य विकल्पों को सूचीबद्ध कर रहा हूं। हालांकि मुझे यकीन नहीं है कि runकिसी तरह का प्रदर्शन दंड है। मैं इसे और अधिक स्पष्ट करने के लिए अपने उत्तर को अपडेट करूंगा।
बेनिटो बर्टोली

1
@ वोड्डन यदि aए है var, तो a?.let{} ?: run{}गारंटी का उपयोग करते हुए कि यह letपूरे दायरे के लिए ठीक से बाध्य होगा । यदि aए है val, तो कोई अंतर नहीं है।
मई

1
@madeinqc यदि a है val, तो let का उपयोग करना अलग है और यह खराब है। मुझे यह लेख समझाने पर बहुत अच्छा लगा - कोटलिन: शून्य चेक के लिए सिर्फ एलईटी का उपयोग न करें
सूफियान

38

नलिन से निपटने के कोटलिन तरीके

सुरक्षित पहुंच संचालन

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted

कार्य करते हैं

user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}

जल्दी निकल जाना

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}

अपरिवर्तनीय छाया

var user : User? = null

fun handleUser() {
  val user = user ?: return //Return if null, otherwise create immutable shadow
  //Work with a local, non-null variable named user
}

डिफ़ॉल्ट मान

fun getUserName(): String {
 //If our nullable reference is not null, use it, otherwise use non-null value 
 return userName ?: "Anonymous"
}

Var की जगह val का प्रयोग करें

valकेवल पढ़ने योग्य है, varपारस्परिक है। यह केवल पढ़ने योग्य गुणों के रूप में उपयोग करने की अनुशंसा की जाती है, वे थ्रेड-सुरक्षित हैं।

लेटइनिट का उपयोग करें

कभी-कभी आप अपरिवर्तनीय गुणों का उपयोग नहीं कर सकते। उदाहरण के लिए, यह एंड्रॉइड पर होता है जब कुछ संपत्ति को onCreate()कॉल में आरंभ किया जाता है । इन स्थितियों के लिए, कोटलिन में एक भाषा सुविधा है जिसे कहा जाता है lateinit

private lateinit var mAdapter: RecyclerAdapter<Transaction>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_transaction)
}

fun updateTransactions() {
   mAdapter.notifyDataSetChanged()
}

मैं पिछले एक "डिफ़ॉल्ट मान" (एल्विस नहीं) कहूंगा, क्योंकि उनमें से 3/4 एल्विस का उपयोग कर रहे हैं।
AjahnCharles

@AjahnCharles समझ में आता है))
लेवॉन

1
यह कचरा है, कोई भी भाषा आधुनिक इससे बेहतर विकल्प के साथ निपट सकती है। प्रोग्रामर के लिए एक लाभ की तुलना में इसकी अधिक कोर है।
JBarros35

10

@Benito बर्टोली के अलावा,

संयोजन वास्तव में अगर-के विपरीत है

"test" ?. let {
    println ( "1. it=$it" )
} ?: let {
    println ( "2. it is null!" )
}

परिणाम है:

1. it=test

लेकिन अगर:

"test" ?. let {
    println ( "1. it=$it" )
    null // finally returns null
} ?: let {
    println ( "2. it is null!" )
}

परिणाम है:

1. it=test
2. it is null!

इसके अलावा, यदि पहले एल्विस का उपयोग करें:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}

परिणाम है:

1. it is null!
2. it=kotlin.Unit

5

उपयोगी तरीकों की जाँच करें, यह उपयोगी हो सकता है:

/**
 * Performs [R] when [T] is not null. Block [R] will have context of [T]
 */
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

/**
 * Checking if [T] is not `null` and if its function completes or satisfies to some condition.
 */
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
    return ifNotNull(this) { it.run(check) } ?: false
}

नीचे उन कार्यों का उपयोग करने के संभावित उदाहरण दिए गए हैं:

var s: String? = null

// ...

if (s.isNotNullAndSatisfies{ isEmpty() }{
   // do something
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.