एरो (->) ऑपरेटर पूर्वता / प्राथमिकता सबसे कम है, या असाइनमेंट / संयुक्त असाइनमेंट की प्राथमिकता सबसे कम है?


18

JLS :

सबसे कम पूर्ववर्ती ऑपरेटर एक लैम्ब्डा अभिव्यक्ति (->) का तीर है , इसके बाद असाइनमेंट ऑपरेटर।

किस दिशा में पीछा किया गया (बढ़ती प्राथमिकता, घटती प्राथमिकता)? - "पीछा किया" का अर्थ है असाइनमेंट में उच्च प्राथमिकता या कम प्राथमिकता है (तीर ऑपरेटर के संबंध में)? मुझे लगता है, बढ़ने में, क्योंकि "सबसे कम" (तीर के लिए) का अर्थ है सबसे कम।

जैसा कि मैं समझता हूं, तीर (->) इस प्रिंसटन ऑपरेटर पूर्वता तालिका (जो सभी असाइनमेंट ऑपरेटरों से नीचे है ) के बहुत नीचे होना चाहिए , इस प्रकार तीर (->) 0 (शून्य) प्राथमिकता स्तर (उस तालिका के अनुसार) है।

क्या मैं अपनी समझ में सही हूं?

एग्जाम में लगता है कि तीर की प्राथमिकता कम से कम असाइनमेंट के समान है ... प्लस ने स्पष्ट किया कि एरो एसोसिएटिविटी लेफ्ट-> टू-> राइट (असाइनमेंट के विपरीत) है। मुझे तीर संबद्धता के लिए कोई JLS उद्धरण नहीं मिला।

मैं हमेशा यह सोचता था कि असाइनमेंट प्राथमिकता मुख्य रूप से किसी कारण से सबसे कम है।


5
The lowest precedence operator is the arrow of a lambda expression.
कायमैन

2
हां, आपकी समझ सही है।
एरान

4
यदि ->निम्न स्थापन है , तो असाइनमेंट संचालकों में निम्न एर की पूर्वता नहीं हो सकती है।
एंडी टर्नर

IntFunction fo = a->b->a-b; // in test सामान्य तौर पर -> की प्राथमिकताएँ / संगति। इसलिए मैंने स्पष्ट करने का निर्णय लिया -> पूर्ववर्तीता / संघातकता तालिका में पूर्ववर्तीता / सहानुभूति स्थान। क्योंकि इसके बारे में अनिश्चित महसूस किया।
कोड पूरा

1
@ आपके उदाहरण से IntUnaryOperator op; op = x -> x;दिलचस्प है। शायद (op = x) -> xइसलिए नहीं माना जाता क्योंकि उत्पादन op = xका एक वैध उदाहरण नहीं है LambdaParameters?
एंडी टर्नर

जवाबों:


13

उद्धृत JLS पाठ से पहले वाले वाक्य पर ध्यान दें :

ऑपरेटरों के बीच वरीयता व्याकरण प्रस्तुतियों के एक पदानुक्रम द्वारा प्रबंधित की जाती है।

जावा भाषा का व्याकरण निर्धारित करता है कि कौन से निर्माण संभव हैं और अंतर्निहित रूप से, ऑपरेटर पूर्वता।

यहां तक ​​कि आपके द्वारा लिंक किए गए प्रिंसटन तालिका भी :

जावा भाषा विनिर्देश में कोई स्पष्ट ऑपरेटर पूर्वता तालिका नहीं है। वेब पर और पाठ्यपुस्तकों में अलग-अलग टेबल कुछ मामूली तरीकों से असहमत हैं।

तो, जावा भाषा का व्याकरण एक असाइनमेंट ऑपरेटर के बाईं ओर लंबो एक्सप्रेशन की अनुमति नहीं देता है और इसी तरह, बाईं ओर असाइनमेंट की अनुमति नहीं देता है ->। इसलिए इन ऑपरेटरों के बीच कोई अस्पष्टता संभव नहीं है और पूर्ववर्ती नियम, हालांकि स्पष्ट रूप से जेएलएस में कहा गया है, अर्थहीन हो जाता है।

यह संकलन करने की अनुमति देता है, उदाहरण के लिए इस तरह के एक मणि, अस्पष्टता के बिना:

static Consumer<String> C;
static String S;
public static void main(String[] args)
{
  Runnable r;
  r = () -> C = s -> S = s;
}

10

सबसे पहले, यहाँ व्यावहारिक मुद्दे की व्याख्या करते हैं।

मान लें कि आपके पास एक परिभाषा है

IntUnaryOperator op;

निम्नलिखित वाक्यविन्यास को स्वीकार किया जाता है, और अपेक्षित रूप से काम करता है:

op = x -> x;

यही है, हमारे पास चर intको सौंपा गया एक पहचान समारोह है op। लेकिन अगर =एक उच्च प्राथमिकता थी, तो हम उम्मीद करेंगे कि जावा इसकी व्याख्या करेगा

(op = x) -> x;

जो वाक्यात्मक रूप से मान्य नहीं है, इस प्रकार एक संकलन त्रुटि होनी चाहिए। इसलिए, असाइनमेंट, व्यवहार में, तीर की तुलना में अधिक पूर्वता नहीं रखता है।

लेकिन निम्नलिखित भी ठीक है (मान tएक वर्ग / आवृत्ति प्रकार का चर int) है:

op = x -> t = x;

यह संकलित करता है, और फ़ंक्शन, यदि लागू किया जाता है, तो ऑपरेंड के मूल्य को असाइन करता है tऔर इसे भी लौटाता है।

इसका मतलब यह है कि तीर में असाइनमेंट की तुलना में अधिक पूर्वता नहीं है t = x। अन्यथा इसकी व्याख्या की जाती

op = ( x -> t ) = x

और स्पष्ट रूप से, ऐसा नहीं है।

इसलिए ऐसा लगता है कि संचालन में समान रूप से पूर्वता है। क्या अधिक है, कि वे सही सहयोगी हैं। यह व्याकरण से पर निहित है JLS अध्याय 19 :

Expression:
  LambdaExpression
  AssignmentExpression

LambdaExpression:
  LambdaParameters -> LambdaBody

...

LambdaBody:
  Expression
  Block

तो लैम्बडा बॉडी का दाहिना हिस्सा हमें वापस मिल जाता है Expression, जिसका अर्थ है कि हम या तो इसके अंदर एक (उच्च प्राथमिकता) लैम्ब्डा हो सकते हैं, या इसमें (उच्च प्राथमिकता) असाइनमेंट कर सकते हैं। "उच्च प्राथमिकता" से मेरा तात्पर्य यह है कि आप उत्पादन नियमों से जितनी गहराई से गुजरते हैं, पहले की अभिव्यक्ति का मूल्यांकन किया जाएगा।

असाइनमेंट ऑपरेटर के लिए भी यही सच है:

AssignmentExpression:
  ConditionalExpression
  Assignment

Assignment:
  LeftHandSide AssignmentOperator Expression

एक बार फिर, असाइनमेंट का दाईं ओर हमें वापस फेंकता है Expression, इसलिए हम एक लंबोदर अभिव्यक्ति या वहां एक असाइनमेंट रख सकते हैं।

इसलिए जेएलएस पाठ पर निर्भर होने के बजाय, व्याकरण हमें स्थिति का अच्छी तरह से परिभाषित विवरण देता है।

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