2012-10-29 12 views
23

मैंने कई दावों को देखा है कि स्कैला गणना सुरक्षित नहीं है। यह सुरक्षित कैसे टाइप नहीं है? ऐसा लगता है कि स्पष्ट तरीके से सुरक्षित प्रकार यह है कि आप एक गणना के मूल्य को एक अलग गणना में पारित नहीं कर सकते हैं।स्कैला: गणना कैसे सुरक्षित नहीं है?

गणना से बचने के लिए क्या नुकसान या चीजें हैं?

उत्तर

33

यह अर्द्ध-सुरक्षित है। यह प्रकार सुरक्षित है एक संकलक कथा है, इसलिए तोड़ना आसान है। उदाहरण के लिए,

trait Parent 
class Boy extends Parent { override def toString = "boy" } 
class Girl extends Parent { override def toString = "girl" } 
def f(g: Girl) = g.toString 

scala> f((new Boy).asInstanceOf[Girl]) 
java.lang.ClassCastException: Boy cannot be cast to Girl 
    at .<init>(<console>:15) 
    ... 

ठीक है, लड़के लड़कियां नहीं हैं।

अब enumerations के साथ की कोशिश करते हैं:

object Test extends Enumeration { val One, Two = Value } 
object Probar extends Enumeration { val Uno, Dos = Value } 
def h(tv: Test.Value) = tv.toString 

scala> h((Probar.Uno).asInstanceOf[Test.Value]) 
res0: java.lang.String = Uno 

प्रतीक्षा, क्या?

def h(pv: Probar.Value) = pv.toString // Add this to the other h in a :paste 

method h:(pv: Probar.Value)java.lang.String and 
method h:(tv: Test.Value)java.lang.String at line 9 
have same type after erasure: (pv: Enumeration#Value)java.lang.String 
      def h(pv: Probar.Value) = pv.toString 

उह, ठीक है, धन्यवाद:

यह कल्पना अन्य अजीब व्यवहार की ओर जाता है?

और फिर संकलक वास्तव में अपने स्वयं के निर्माण के रूप में नहीं समझती के बाद से Enumeration, यह आप बाहर तरीकों से मदद नहीं कर सकता आप उम्मीद कर सकते:

scala> def oops(tv: Test.Value) = tv match { case Test.One => "okay" } 
oops: (tv: Test.Value)java.lang.String 
// No incomplete match warning? Okay.... 

scala> oops(Test.Two) 
scala.MatchError: Two (of class scala.Enumeration$Val) 
    at .oops(<console>:8) 
    ... 

तो अगर आप वास्तव में अपेक्षाकृत सीमित मायनों में इसका इस्तेमाल करते हैं इरादे के अनुसार, यह प्रकार की सुरक्षा प्रदान करता है। लेकिन इसमें अन्य पैटर्न की शक्ति और मजबूती नहीं है, जैसे कि:

// In REPL, :paste the next three lines 
sealed trait Foo 
object Bar extends Foo 
object Baz extends Foo 

scala> def safe(f: Foo) = f match { case Bar => "okay" } 
<console>:9: warning: match is not exhaustive! 
missing combination   Baz 

     def safe(f: Foo) = f match { case Bar => "okay" } 
         ^

धन्यवाद, कंपाइलर!

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