के बीच अंतर कैसे करता है मेरा other question डुप्लिकेट के रूप में बंद हो गया है, इसलिए मैं इसे फिर से कोशिश करूंगा। मैंने this question भी पढ़ा है और जो मैं पूछ रहा हूं वह अलग है। मुझे () => Type
से अलग कैसे आंतरिक कार्यान्वयन सीखने में रूचि है।स्कैला() => टी और => टी
मेरा भ्रम जावप और cfr डिस्सेप्लर देखने से आ रहा है जो दो मामलों में कोई अंतर नहीं दिखाता है।
उदा। ParamTest.scala:
object ParamTest {
def bar(x: Int, y: => Int) : Int = if (x > 0) y else 10
def baz(x: Int, f:() => Int) : Int = if (x > 0) f() else 20
}
javap उत्पादनjavap ParamTest.scala
:
public final class ParamTest {
public static int baz(int, scala.Function0<java.lang.Object>);
public static int bar(int, scala.Function0<java.lang.Object>);
}
सीएफआर decompiled उत्पादनjava -jar cfr_0_118.jar ParamTest$.class
:
import scala.Function0;
public final class ParamTest$ {
public static final ParamTest$ MODULE$;
public static {
new ParamTest$();
}
public int bar(int x, Function0<Object> y) {
return x > 0 ? y.apply$mcI$sp() : 10;
}
public int baz(int x, Function0<Object> f) {
return x > 0 ? f.apply$mcI$sp() : 20;
}
private ParamTest$() {
MODULE$ = this;
}
}
संपादित करें 1: स्काला सिंटेक्स पेड़: scalac -Xprint:parse ParamTest.scala
package <empty> {
object ParamTest extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def bar(x: Int, y: _root_.scala.<byname>[Int]): Int = if (x.$greater(0))
y
else
10;
def baz(x: Int, f: _root_.scala.Function0[Int]): Int = if (x.$greater(0))
f()
else
20
}
}
संपादित 2: मेलिंग सूची अनुसंधान:
मेलिंग सूची जो अनिवार्य रूप से कहा गया है कि => T
() => T
के रूप में कार्यान्वित किया जाता है पर इस interesting post पढ़ें। उद्धरण:
सबसे पहले,
f: => Boolean
को देखो, यह वास्तव में एक
Function0
के रूप में कार्यान्वित किया जाता है हालांकि यह एक "द्वारा नाम पैरामीटर" कहा जाता है
f:() => Boolean
बस दोनों सिरों पर इस्तेमाल विभिन्न वाक्यविन्यास के साथ।
अब मैं this answer द्वारा और भी उलझन में हूं जो स्पष्ट रूप से कहता है कि दोनों अलग हैं।
प्रश्न:
- कैसे स्काला
baz
सेbar
भेद है? दोनों के लिए विधि हस्ताक्षर (कार्यान्वयन नहीं) decompiled कोड में समान हैं। - क्या दो परिदृश्यों में अंतर संकलित बाइटकोड में नहीं टिकता है?
- क्या असंगत कोड गलत है?
- संपादित करें 1 संपादित करने के बाद जोड़ा गया: मैंने पाया कि स्केलैक सिंटैक्स पेड़ एक अंतर दिखाता है,
bar
का दूसरा तर्क_root_.scala.<byname>[Int]
है। यह क्या करता है?कोई स्पष्टीकरण, scala source या समकक्ष छद्म कोड में पॉइंटर्स उपयोगी होंगे। - से ऊपर संपादित 2 देखें: क्या उद्धृत ब्लॉक सही है? जैसा कि
Function0
का एक विशेष उप-वर्ग है?
JVM बाइटकोड में इन प्रकारों का प्रतिनिधित्व कैसे किया जाता है यह महत्वपूर्ण क्यों है? वे स्कैला कोड में अलग हैं, यह महत्वपूर्ण है (जब तक आप जावा से स्कैला को कॉल करने की कोशिश नहीं कर रहे हैं, लेकिन यह नहीं है कि आप क्या पूछ रहे हैं)। –
क्योंकि स्कैला उस तरह से काम करता है। यह स्कैला कोड को .class फ़ाइलों में संकलित करता है और JVM में निष्पादित करता है। इसलिए .class फ़ाइल में आवश्यक और पर्याप्त जानकारी होनी चाहिए। स्कैला स्रोत फाइलें बिल्कुल महत्वपूर्ण नहीं हैं। [लिंक किए गए प्रश्न] देखें (http://stackoverflow.com/questions/40246137/what-does-double-right-arrow-type-with-no-lhs-mean-in-function-argument/), आप पुन: पेश कर सकते हैं 'ParamTest.scala' स्रोत फ़ाइल को हटाने के बाद 'foo (baz, 100)' को कॉल करने में त्रुटि। – vsnyc
इस प्रश्न के लिए एक और प्रेरणा है [यह उत्तर] (http://stackoverflow.com/a/13337382/2063026) जहां सबसे ऊपर की टिप्पणी (160) जोर देती है, मैं उद्धरण देता हूं: "इसके अलावा," कॉल-बाय-नाम "में नामों से कोई लेना देना नहीं है। '=> Int' 'Int' से एक अलग प्रकार है; यह" कोई तर्क नहीं है जो एक इंट बनाम बनाम इंट उत्पन्न करेगा "। लेकिन जैसा कि हम ऊपर देखते हैं, यह मामला नहीं है। कॉल-बाय-नाम आलसी मूल्यांकन के साथ करना है, न कि यह कोई तर्क का कार्य है ... – vsnyc