假设我想要一个方法来输出某些东西,在这种情况下是一个字符串或整数。我可以这样做:
def outString(str: String) {
str // or "return str"
}
并按照以下方式运行:outString("foo")
但是我也可以避免将特定类型初始化为参数并且它可以工作:
def outString(str: Any) {
str
}
并按以下方式运行:outString("foo")
或outString(123)
。
鉴于他们都工作并假设你不总是知道所传递的参数的类型,使用Any
对特定参数类型有任何陷阱吗? Any
是否进行任何类型的自动类型检查,如解释语言会降低代码速度?
答案 0 :(得分:6)
在运行时性能等方面,以下两种方法没有实际区别:
def genericLog[A](a: A): Unit = println(a.toString)
def anyLog(a: Any): Unit = println(a.toString)
只要你只使用Any
上的方法,而不是使用isInstanceOf
或asInstanceOf
或模式匹配执行运行时类型检查或强制转换,就会有&#39>没有性能影响。
问题是there aren't many things you can do with Any
,你可以做的事情(检查相等性和转换为字符串)并不是非常有用(例如,尝试打印数组)。一旦你需要写这样的东西:
def anyLog(a: Any): Unit = a match {
case i: Int => println("Int: " + i)
case s: String => println("String: " + s)
case other => println("Other: " + other)
}
您回到了运行时类型检查的范围内,这确实会对性能产生影响,但更重要的是会破坏您和其他人推理代码的能力。
所以是的,如果你绝对确定除了致电toString
之外你永远不需要做任何事情,你可以在这里使用Any
。如果您正在撰写惯用的Scala代码,这种情况不会经常出现,我个人建议明确地避免Any
无处不在,包括像这样的情况。
更新:正如@pedrofurla在下面的评论中指出的那样,采用Int
参数的方法与采用Any
的方法之间存在一个重要区别。在Any
- take方法中,整数参数将被加框,而它在({1}} - 采用方法中不一定(必然)。
非常非常容易在Scala(Int
或1.toString
中意外地装箱原语,例如),并且通常它可能不会你应该担心的事情,直到基准测试或分析器告诉你它在特定情况下是一个问题。但这是避免println(1)
参数的另一个原因,因为非泛型Any
参数或带Int
注释的泛型参数都不会导致不必要的装箱。< / p>