如何在Scala中强制转换变量?


199

给定类型为变量的变量Graphics,如何Graphics2D在Scala中将其强制转换为?

Answers:


282

首选技术是使用模式匹配。这使您可以优雅地处理所涉及的值不是给定类型的情况:

g match {
  case g2: Graphics2D => g2
  case _ => throw new ClassCastException
}

该块复制了该asInstanceOf[Graphics2D]方法的语义,但具有更大的灵活性。例如,您可以为各种类型提供不同的分支,从而有效地同时执行多个条件转换。最后,您实际上并不需要在“包罗万象”区域中引发异常,也可以返回null(或最好是None),也可以输入一些不使用的后备分支Graphics2D

简而言之,这确实是要走的路。它在语法上比稍大asInstanceOf,但增加的灵活性几乎总是值得的。


19
+1是因为它很有趣,但在这种情况下有点过多。是不是
尤金·横田

如果我已经模式匹配但丢失了对强制转换值的引用,该怎么办:<code> base match {case MyConcrete(value)=> base.asInstanceOf [MyConcrete] .something(value)} </ code>,有没有一种方法来获取“即使想通过利用“ case MyConcrete(value)”执行的“ unapply”调用来提取“ value”,也强制转换为MyConcrete?
ithkuil 2010年

4
试试看:base match { case base @ MyConcrete(value) => base.something(value) } 显然,阴影base是可选的。您可以轻松地使用其他变量名。
丹尼尔·史派瓦克

我不明白的是,如何将这种模式匹配的结果转换为变量?就像在Java中,如果它是String a =(String)b; 标量相当于什么?
詹姆斯·麦克马洪

@JamesMcMahonval gResult = g match { case g2: Graphics2D => g2 case _ => throw new ClassCastException }
Kevin Meredith

224
g.asInstanceOf[Graphics2D];

36
一旦我习惯了Scala,我就学会了不使用asInstanceOf,因为它违反了具有静态类型系统的目的,并且令人讨厌。
尤金·横田

26
不幸的是,这是使用Swing时的常见操作。对于自定义绘画操作,您需要重写'public void paintComponent(Graphics g)'方法。Graphics参数实际上是一个Graphics2D实例,但是需要强制转换。模式匹配版本可能比保证的更为详细。切记:谨慎避免混淆性过高和冗长!
hohonuuli

7
@hohonuuli我认为在特定情况下可以进行强制转换,但是如果使用scala-swing组件,paintComponent的参数已经是Graphics2D,因此不需要
强制转换

2
为什么这么长?为什么“ asInstanceOf when只能是“ as”或“ asof”关键字或方法?或者为什么他们不只是采用C ++和Java方式作为选项,因为这是常规做法,因此没有大问题?
LEMUEL ADANE 2014年

16
@LemuelAdane实际上,您在使用强制转换是一种代码味道,使它们变得更简单没有任何意义。
丹妮丝2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.