gpt4 book ai didi

Scala:枚举为什么类型不安全?

转载 作者:行者123 更新时间:2023-12-03 01:26:48 26 4
gpt4 key购买 nike

我看到很多断言 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

呃,好的,谢谢?

然后,由于编译器并不真正将 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" }
^

谢谢编译器!

关于Scala:枚举为什么类型不安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13129358/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com