Scala:枚举不是安全的?
发布时间:2020-12-16 09:46:04 所属栏目:安全 来源:网络整理
导读:我看到了Scala枚举不是类型安全的一些断言。怎么不安全?它似乎以明显的方式安全,因为您不能将一个枚举的值传递给不同的枚举。 枚举有什么陷阱或要避免的事情? 解决方法 这是半安全的它是类型安全的是一个编译器小说,所以很容易打破。例如, trait Parent
我看到了Scala枚举不是类型安全的一些断言。怎么不安全?它似乎以明显的方式安全,因为您不能将一个枚举的值传递给不同的枚举。
枚举有什么陷阱或要避免的事情? 解决方法
这是半安全的它是类型安全的是一个编译器小说,所以很容易打破。例如,
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) ... 好吧,男孩不是女孩。 现在我们来试试枚举: 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 呃,好的,谢谢 然后,由于编译器并不真正了解枚举作为自己的构造,它无法帮助您以预期的方式: 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" } ^ 谢谢,编译器! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |