【问题标题】:Scala short and type safe cast operatorScala 短类型安全转换运算符
【发布时间】:2012-04-25 21:01:01
【问题描述】:

我不喜欢 Scala 的 isInstanceOf 和 asInstanceOf 方法——它们很长而且 asInstanceOf 会抛出异常,所以我们需要同时使用它。更好的方法是使用模式匹配:Scala: How do I cast a variable?,但对于非常简单的操作,它也可能相对较长。在 C# 中,我们有 'is' 和 'as' 运算符,所以我想在 Scala 中用 this 实现隐式定义。我的代码如下所示:

scala> class TypeCast(x:Any){
     | def is[T](t:Class[T]) = t.isInstance(x) 
     | def as[T](t:Class[T]):Option[T] = if(t.isInstance(x)) Option(t.cast(x)) else None
     | }
defined class TypeCast

scala> implicit def TypeCastID(x:Any)=new TypeCast(x)
TypeCastID: (x: Any)TypeCast

scala>  123 as classOf[String]
res14: Option[String] = None

scala> "asd" as classOf[String]
res15: Option[String] = Some(asd)

它有一个优点——实现空对象模式,但也有缺点:

  • 需要使用 classOf[T] 运算符 - 太长了

  • 这种简单操作的隐式def连接的开销

所以没有实际理由使用它。 我想知道有没有什么方法可以实现这个而不需要使用 classOf[T]?

【问题讨论】:

  • 在我看来,isInstanceOfasInstanceOf 的名字比较长而且不方便是好的。通常,您会希望避免动态类型检查和强制转换,而是使用更好的 OO 风格方法(多态性)或模式匹配(功能风格)。不方便的名称鼓励您不要过多地使用它们。在您的标题中,您要求使用“类型安全的演员表操作员”。根据定义,强制转换永远不是类型安全的。
  • 我想会有类似的评论。总的来说,我同意你的观点,好的设计和模式匹配要好得多。但有时恕我直言'as'符号更短更清晰。例如,我们可以使用设计不如我们需要的第三方库。它还返回 Option[T] 而不是 T 所以它更安全。最后:回答这个问题最重要的是让我对 Scala 有更多的了解:)

标签: scala


【解决方案1】:

好吧,您可以在 TypeCast 类中创建的 def 中将其缩短。因此,您可以只依赖类型,而不是为其提供参数。这样会缩短很多。例如,这可能类似于:

class TypeCast(x : Any) {
    def is[T : Manifest] = manifest.erasure.isInstance(x)
    def as[T : Manifest] : Option[T] = if (manifest.erasure.isInstance(x)) Some(x.asInstanceOf[T]) else None
}

未来的调用可能如下所示:

scala> 123.as[String]
res0: Option[String] = Some(123)
scala> class A; class B extends A
defined class A
defined class B
scala> new B
res1: B
scala> res1.is[Int]
res2: Boolean = false
scala> res1.as[Int]
res3: Option[Int] = None

更新:我添加了清单以避免类型检查错误

【讨论】:

  • 我尝试了类似的解决方案,但不幸的是这不能正常工作:A 类; B类扩展A; val b=新B; b.as[Int] 给 mi Some(instance-of-B) 而不是 None 并且 b.is[Int] 返回 true
  • 看来你可以使用清单来清理。我会更新代码。
  • 谢谢!我以前从未听说过 Manifest。
  • @theres 你知道选角操作员是为了不鼓励选角吗?
  • 这不适用于盒装类型。 1.is[Int] 是假的,因为 1 是 int :)
猜你喜欢
  • 2011-01-15
  • 2012-01-25
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多