2017-04-18 8 views
5

के लिए सुरक्षा मैं कुछ HTML निर्माण के लिए डीएसएल लागू करने वाले दस्तावेज़ों से official example का उपयोग करने जा रहा हूं।कोटलिन प्रकार सुरक्षित निर्माता डीएसएल, बाहरीतम फ़ंक्शन

Kotlin 1.1 के बाद से, @DslMarker एनोटेशन हमें हमारी कक्षाओं में कार्यों का दायरा सीमित करने के लिए, उदाहरण की तरह @HtmlTagMarker एनोटेशन के साथ करता है की अनुमति देता है।

html { 
    body { 
     body { // this in an error, as it's a function call on the outside Html element 
     } 
    } 
} 

बहरहाल, यह सबसे बाहरी समारोह है, जो डीएसएल के लिए प्रवेश बिंदु है घोंसला बनाने से नहीं रोकता है: जब इस तरह गलत तरीके से संरचित कोड लिखने की कोशिश कर यह हमें एक त्रुटि देता है। उदाहरण के लिए, उदाहरण के साथ के रूप में यह अब है, यह नीचे समस्याओं के बिना लिखा जा सकता है:

html { 
    html { 
    } 
} 

वहाँ एक डीएसएल इस संबंध में सुरक्षित बनाने के लिए कोई तरीका है?

उत्तर

6

शायद यह किसी भी तरह एक और अधिक सुरुचिपूर्ण तरीके से किया जा सकता है, लेकिन मैं एक मिलान हस्ताक्षर रिसीवर प्रकार के लिए परिभाषित के साथ एक समारोह पर DeprecationLevel.ERROR साथ @Deprecated एनोटेशन का उपयोग कर सकते हैं सुझाव है, उदाहरण के लिए:

@Deprecated("Cannot be used in a html block.", level = DeprecationLevel.ERROR) 
fun HtmlReceiver.html(action: HtmlReceiver.() -> Unit): Nothing = error("...") 

या यह एक सदस्य समारोह हो सकता है। वैसे, आईडीई पूर्णता इस बात के आधार पर थोड़ा अलग तरीके से व्यवहार करती है कि यह एक विस्तार या सदस्य है या नहीं।

html { 
    html { // Error: Cannot be used in a html block. 
    } 
} 

(demo of this code)

उच्च-स्तरीय समारोह अभी भी अपनी FQN उदा एक डीएसएल ब्लॉक के अंदर कहा जा सकता है:

यह आंतरिक एक अवैध तरह कॉल कर देगा com.example.html { }, इसलिए यह चाल केवल उपयोगकर्ताओं को गलती से शीर्ष स्तर के फ़ंक्शन को कॉल करने से बचाती है।

+0

यह मूल रूप से सही है, धन्यवाद! – zsmb13

संबंधित मुद्दे