कोटलिन समर्थन क्षेत्र के लिए क्या है?


93

एक जावा डेवलपर के रूप में, एक बैकिंग क्षेत्र की अवधारणा मेरे लिए थोड़ी विदेशी है। दिया हुआ:

class Sample {
    var counter = 0 // the initializer value is written directly to the backing field
    set(value) {
        if (value >= 0) field = value
    }
}

इस समर्थन क्षेत्र के लिए क्या अच्छा है? कोटलिन डॉक्स ने कहा:

कोटलिन में वर्गों के पास खेत नहीं हो सकते। हालांकि, कभी-कभी कस्टम एक्सेसर्स का उपयोग करते समय एक बैकिंग फ़ील्ड होना आवश्यक है

क्यों? गुण का नाम सेटर के अंदर उपयोग करने से क्या अंतर होता है, उदाहरण के लिए। *

class Sample {        
    var counter = 0
    set(value) {
        if (value >= 0) this.counter = value // or just counter = value?
    }
}

18
प्रॉपर्टी में ही सेटर का उपयोग करने से एक अंतहीन पुनरावृत्ति हो जाएगी क्योंकि प्रॉपर्टी को कुछ मूल्य प्रदान करने के बाद हमेशा सेटर को कॉल किया जाएगा।
फनलजंक

1
@Strelok मेरा बुरा .... मैं मान रहा था कि कोटलिन this.counter = valueके डॉक्स पढ़ने पर जावा के बराबर ही है।
युधिष्ठिर आर्य ५'१ira को ira:

5
यह लेख फील्ड बनाम संपत्ति के लिए है।
अविनाश

जवाबों:


86

क्योंकि, का कहना है कि अगर आप की जरूरत नहीं है fieldकीवर्ड, आप में सक्षम नहीं होगा वास्तव में स्थापित करने के लिए / में मूल्य प्राप्त get()या set(value)। यह आपको कस्टम एक्सेसर्स में बैकिंग फ़ील्ड का उपयोग करने में सक्षम बनाता है।

यह आपके नमूने के बराबर जावा कोड है:

class Sample {
    private int counter = 0;
    public void setCounter(int value) {
        if (value >= 0) setCounter(value);
    }
    public int getCounter() {
        return counter;
    }
}

जाहिरा तौर पर यह अच्छा नहीं है, क्योंकि सेटर सिर्फ अपने आप में एक इनफिनिटी रिकर्सन है, कभी भी कुछ भी नहीं बदल रहा है। कोटलिन में याद रखें जब भी आप foo.bar = valueइसे लिखते हैं तो इसे एक के बजाय एक सेटर कॉल में अनुवादित किया जाएगा PUTFIELD


EDIT: जावा के पास फ़ील्ड हैं जबकि कोटलिन में गुण हैं , जो कि खेतों की तुलना में उच्च स्तरीय अवधारणा है।

दो प्रकार के गुण हैं: एक बैकिंग फ़ील्ड के साथ, एक बिना।

एक समर्थन क्षेत्र के साथ एक संपत्ति एक क्षेत्र के रूप में मूल्य संग्रहीत करेगी। वह फ़ील्ड मेमोरी में भंडारण मूल्य को संभव बनाता है। ऐसी संपत्ति का एक उदाहरण firstऔर secondगुण है Pair। वह संपत्ति इन-मेमोरी प्रतिनिधित्व को बदल देगी Pair

एक समर्थन क्षेत्र के बिना एक संपत्ति को सीधे मेमोरी में संग्रहीत करने के अलावा अन्य तरीकों से अपने मूल्य को स्टोर करना होगा। यह अन्य गुणों से गणना की जानी चाहिए, या, वस्तु ही। ऐसी संपत्ति का एक उदाहरण indicesविस्तार संपत्ति है List, जो एक क्षेत्र द्वारा समर्थित नहीं है, लेकिन sizeसंपत्ति के आधार पर एक गणना परिणाम है । तो यह इन-मेमोरी प्रतिनिधित्व को नहीं बदलेगा List(जो कि यह बिल्कुल नहीं कर सकता क्योंकि जावा स्टेटिकली टाइप किया गया है)।


जवाब के लिए धन्यवाद! मेरा बुरा ... मैं मान रहा था कि this.counter = valueजावा समकक्ष के साथ भी ऐसा ही है।
युधिष्ठिर आर्य

कहीं भी प्रलेखित? धन्यवाद :)
Alston


1
बहुत सारी फजी व्याख्याएँ। हम सीधे तौर पर यह क्यों नहीं कह सकते हैं, कि fieldयह पॉइंटर की तरह है या किसी मौजूदा सदस्य चर का संदर्भ है। चूँकि get/setतुरंत अनुसरण करता counterहै, इसलिए fieldकीवर्ड एक संदर्भ है counter। सही?
आइजनफील्ड

@typelogic यह उत्तर जावा / जेएस बैकग्राउंड वाले प्रोग्रामर्स के लिए सबसे अधिक अनुरूप है (पीछे फिर कोई कोटलिन / नेटिव नहीं है), C / C ++ नहीं। जो आपको फजी लगता है वह कुछ और लोगों के लिए ब्रेड और बटर है।
उल्लास

32

प्रारंभ में, मुझे भी इस अवधारणा को समझने में कठिन समय लगा। तो मैं आपको एक उदाहरण की मदद से इसे समझाता हूं।

इस कोटलिन वर्ग पर विचार करें

class DummyClass {
    var size = 0;
    var isEmpty
        get() = size == 0
        set(value) {
            size = size * 2
        }
}

अब जब हम कोड को देखते हैं, तो हम देख सकते हैं कि इसमें 2 गुण हैं - size(डिफ़ॉल्ट एक्सेसर्स के साथ) और isEmpty(कस्टम एक्सेसर्स के साथ)। लेकिन इसका केवल 1 क्षेत्र है size। यह समझने के लिए कि इसमें केवल 1 फ़ील्ड है, आइए हम इस वर्ग के समकक्ष जावा देखते हैं।

Android स्टूडियो में टूल्स -> कोटलिन -> कोटलिन बाइटकोड दिखाएं। Decompile पर क्लिक करें।

   public final class DummyClass {
   private int size;

   public final int getSize() {
      return this.size;
   }

   public final void setSize(int var1) {
      this.size = var1;
   }

   public final boolean isEmpty() {
      return this.size == 0;
   }

   public final void setEmpty(boolean value) {
      this.size *= 2;
   }
}

स्पष्ट रूप से हम देख सकते हैं कि जावा वर्ग के लिए केवल गेटटर और सेटर फ़ंक्शन हैं isEmpty, और इसके लिए कोई फ़ील्ड घोषित नहीं किया गया है। इसी तरह कोटलिन में, संपत्ति के लिए कोई समर्थन क्षेत्र नहीं है isEmpty, क्योंकि संपत्ति उस क्षेत्र पर बिल्कुल भी निर्भर नहीं करती है। इस प्रकार कोई समर्थन क्षेत्र नहीं है।


अब हमें isEmptyप्रॉपर्टी के कस्टम गेट्टर और सेटर को हटा दें ।

class DummyClass {
    var size = 0;
    var isEmpty = false
}

और उपरोक्त वर्ग का जावा समतुल्य है

public final class DummyClass {
   private int size;
   private boolean isEmpty;

   public final int getSize() {
      return this.size;
   }

   public final void setSize(int var1) {
      this.size = var1;
   }

   public final boolean isEmpty() {
      return this.isEmpty;
   }

   public final void setEmpty(boolean var1) {
      this.isEmpty = var1;
   }
}

यहाँ हम दोनों क्षेत्रों sizeऔर देखते हैं isEmptyisEmptyएक समर्थन क्षेत्र है क्योंकि isEmptyसंपत्ति के लिए गेट्टर और सेटर इस पर निर्भर करते हैं।


4
अच्छे खर्च। धन्यवाद
सोनू संजीव

1
वास्तव में, स्पष्टीकरण के लिए धन्यवाद। मैं भी जावा से कोटलिन आया हूं, और गुणों की अवधारणा मेरे लिए नई है। लेकिन मैं इसे समझ गया हूं, धन्यवाद और मार्गदर्शक। :)
यामाशिरो रियोन

भगवान आपको आशीर्वाद दे।
एंड्रिया सियोकारेल्ली

मुझे यह उत्तर पसंद है कि यह ईमानदारी से तथ्यों का हवाला देता है। मैं अभी भी संदेह में हूं, क्योंकि C # को fieldकीवर्ड की कोई आवश्यकता नहीं है क्या यह संभव है कि कोटलीन का एक भाषा सुधार इस अजीब fieldकीवर्ड को हटा देगा और असहाय आत्माओं को अनंत पुनरावर्तन के रसातल में गिरने से बचाएगा?
आइजनफील्ड

9

राज्य परिवर्तन पर सत्यापन या ट्रिगरिंग इवेंट चलाने के लिए बैकिंग फ़ील्ड अच्छे हैं। उस समय के बारे में सोचें जब आपने जावा सेटर / गेट्टर में कोड जोड़ा है। बैकिंग फ़ील्ड समान परिदृश्य में उपयोगी होंगे। जब आप नियंत्रण करने या बसने / पाने वालों की दृश्यता की आवश्यकता होती है तो आप बैकिंग फ़ील्ड का उपयोग करेंगे।

फ़ील्ड नाम के साथ फ़ील्ड असाइन करते समय, आप वास्तव में सेटर (यानी set(value)) को लागू कर रहे हैं । हमारे पास आपके उदाहरण में, this.counter = valueतब तक सेट (मान) में पुनरावृत्ति होगी जब तक कि हम अपने स्टैक को ओवरफ्लो नहीं करते। का उपयोग करते हुए fieldबाइपास सेटर (या गेटर) कोड।


क्षमा करें, लेकिन आपके स्पष्टीकरण में वह शब्द शामिल है जिसे समझाने की आवश्यकता है। और फिर, आपने पहले एक जावा परिदृश्य का हवाला दिया और फिर अचानक चेतावनी के बिना आप एक वास्तविक कोटलिन के बयान के लिए लेंस स्विच करते हैं। कीवर्ड के लिए कोटलिन की आवश्यकता C #field में नहीं है, इसलिए हमें आपके द्वारा उद्धृत एक बेहतर स्पष्टीकरण की आवश्यकता है।
आइजनफील्ड

2

मेरी समझ फ़ील्ड पहचानकर्ता का उपयोग उस संपत्ति के मूल्य के संदर्भ में प्राप्त या सेट के रूप में कर रही है , जब आप संपत्ति के मूल्य को प्राप्त या सेट में बदलना चाहते हैं ।

उदाहरण के लिए:

class A{
    var a:Int=1
        get(){return field * 2}    // Similiar to Java: public int geta(){return this.a * 2}
        set(value) {field = value + 1}
}

फिर:

var t = A()
println(t.a)    // OUTPUT: 2, equal to Java code: println(t.a * 2)
t.a = 2         // The real action is similar to Java code: t.a = t.a +1
println(t.a)    // OUTPUT: 6, equal to Java code: println(t.a * 2)

0

शब्दावली backing fieldरहस्य से भर जाती है। कीवर्ड प्रयोग किया जाता है fieldget/setविधियों, तुरंत सदस्य चर रहा है कि के बारे में करने के लिए अगले इस प्रकार होना करने के लिए मिलता है या सेट इस दरवाजा सुरक्षात्मक तरीकों तंत्र के माध्यम से। fieldकीवर्ड सिर्फ सदस्य चर किया जा रहा है कि को संदर्भित करता है सेट या प्राप्त । वर्तमान Kotlin पर, आप के अंदर सीधे सदस्य चर का उल्लेख कर सकते नहीं प्राप्त या सेट सुरक्षात्मक दरवाजा तरीकों क्योंकि यह दुर्भाग्य अनंत प्रत्यावर्तन के लिए परिणाम होगा, क्योंकि यह फिर से लागू करेगा प्राप्त या सेट और इस तरह गहरी खाई में नीचे क्रम एलईडी।

में सी # हालांकि, आप सीधे गेटर / सेटर तरीकों के अंदर सदस्य चर संदर्भित कर सकते हैं। मैं इस विचार की तुलना करने का हवाला दे रहा हूं कि यह fieldकीवर्ड यह है कि वर्तमान कोटलिन इसे कैसे लागू कर रहा है, लेकिन मुझे उम्मीद है कि इसे बाद के संस्करणों में हटा दिया जाएगा और हमें अनंत पुनरावृत्ति के परिणामस्वरूप सीधे सदस्य चर का संदर्भ देने की अनुमति देगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.