स्काला ऑप्शन (अशक्त) कोई नहीं के रूप में की उम्मीद है, लेकिन मुझे कुछ मिला (0)


9
val i: java.lang.Integer = null
val o: Option[Int] = Option(i) // This yields Some(0)

null: java.lang.Integerस्काला में बदलने का सुरक्षित तरीका क्या है Option[Int]?


1
क्या आप प्रश्न में अपना कोड पेस्ट कर सकते हैं?
Виталий Олегович

जवाबों:


17

आप मिश्रण कर रहे हैं Intऔर java.lang.Integerइसलिए

val i: java.lang.Integer = null
val o: Option[Int] = Option(i)

संक्षेप में धर्मान्तरित

val o: Option[Int] = Option(Integer2int(i))

जो बन जाता है

val o: Option[Int] = Option(null.asInstanceOf[Int])

इस प्रकार

val o: Option[Int] = Some(0)

अगर आप साथ काम करना चाहते हैं java.lang.Integer, तो लिखें

val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None

2
यह हाल ही में कहीं पूछा गया था, इसलिए यह एक असली गेटा है। शायद यह समस्या अनुमान पर निर्भर कर रही है: Option[Integer](i).map(_.intValue)मेरे लिए सबसे मुहावरेदार लगता है, क्योंकि यह कहता है कि यह क्या कर रहा है। इसके अलावा, -Xlintचेतावनी को देखने के लिए उपयोग करें val o!
सोम-संवत

एक बॉक्सिंग राउंडट्रिप से बचने के लिए, `val x: Option [Int] = Option (i) .asInstanceOf [Option [Int]]` जहाँ Integerपर अनुमान लगाया गया है।
सोम-संवत

7

ऐसा इसलिए हो रहा है क्योंकि आप इसे बना रहे हैं Option, और इसे Intएक चरण में (@ मारियोगैलिक के उत्तर में) परिवर्तित कर रहे हैं बताता है कि ऐसा क्यों हो रहा है)।

यह वही है जो आप चाहते हैं:

scala> val o: java.lang.Integer = null
o: Integer = null

scala> val i: Option[Int] = Option(o).map(_.toInt)
i: Option[Int] = None

scala> val o1: java.lang.Integer = 1
o1: Integer = 1

scala> val i1: Option[Int] = Option(o1).map(_.toInt)
i1: Option[Int] = Some(1)

दूसरे उत्तर पर, मैंने सुझाव दिया _.intValue। मुझे लगता है कि यह केवल रूपांतरण कॉल बचाता है।
सोम-संवत

1

पहले इसी मुद्दे का सामना किया। इस संदिग्ध व्यवहार को स्काला टीम द्वारा जाना जाता है। ऐसा लगता है कि इसे बदलने से कहीं और कुछ टूट जाता है। देखें https://github.com/scala/bug/issues/11236 और https://github.com/scala/scala/pull/5176


2
वास्तव में संदिग्ध व्यवहार nullपूर्णांक के रूप में व्यवहार कर रहा है । यह संभवतः एक हैंगओवर है Cजहां 0से एक पॉइंटर को असाइन करना ठीक है । लेकिन इसका मतलब यह नहीं है कि परिणामी सूचक है 0, इसलिए यह दोनों के बीच भी स्विच करने के लिए चकमा दे रहा है C
टिम

Integerशायद जावा कोड से आया है इसलिए 'एक पूर्णांक के रूप में शून्य का इलाज न करें' एक कार्रवाई योग्य सलाह नहीं है। और हम स्पष्ट रूप से nullability का उपयोग करने के लिए इस Integer की जाँच करें Option.apply। इसलिए हमें अप्रत्याशित आउटपुट w / o स्पष्ट रूप से किसी भी असुरक्षित ऑपरेशन को करने के लिए मिलता है।
सिमपद्जो

मुद्दा यह है कि आप जावा को "संदिग्ध व्यवहार" के लिए दोषी नहीं ठहरा सकते हैं जब मूल कारण जावा है। एक्शन करने योग्य सलाह का अर्थ है निहितार्थ रूपांतरण का उपयोग करने के बजाय जावा प्रकारों से समान स्केल प्रकारों में स्पष्ट रूपांतरण। (इसलिए JavaConvertersइसके बजाय JavaConversion)
टिम

1
खैर, मैं इस मामले में संकलन त्रुटि / चेतावनी नहीं छोड़ने के लिए स्काला को दोषी ठहरा सकता हूं। रनटाइम क्रैश भी बेहतर होगा। यहां तक ​​कि अकेले मेरी कंपनी में स्काला में 5+ वर्षों के अनुभव वाले 2 डेवलपर्स ने इस समस्या को मारा है।
सिम्पडोजो

1
@ यह केवल कॉल करके, रनटाइम क्रैश प्राप्त करना बहुत आसान होगा theInteger.intValue()। उस दुर्घटना से बचना एक अतिरिक्त रनटाइम चेक की लागत है। स्काला के पुराने संस्करणों में, इस रूपांतरण ने वास्तव में एक NPE का उत्पादन किया; इसे बग के रूप में रिपोर्ट किया गया था, और वर्तमान व्यवहार के लिए तय किया गया था। मैं एक स्काला विशेषज्ञ नहीं हूं, लेकिन मैंने scala-dev # 355 और scala # 5176 को ऐतिहासिक संदर्भ के रूप में खोदा ।
अमलियॉ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.