Alp*_*ran 0 types arguments scala
假设我要输出的方法的东西,在这种情况下,字符串或整数.我可以这样做:
def outString(str: String) {
str // or "return str"
}
Run Code Online (Sandbox Code Playgroud)
并像这样运行: outString("foo")
但我也可以避免将特定类型初始化为参数,它会起作用:
def outString(str: Any) {
str
}
Run Code Online (Sandbox Code Playgroud)
并运行它像这样:outString("foo")或outString(123).
鉴于它们都工作并假设你并不总是知道所传递的Any参数的类型,使用特定参数类型是否有任何陷阱?是否Any做检查类似解释的语言也将减缓对代码进行任何类型的自动型的?
在运行时性能等方面,以下两种方法之间没有实际区别:
def genericLog[A](a: A): Unit = println(a.toString)
def anyLog(a: Any): Unit = println(a.toString)
Run Code Online (Sandbox Code Playgroud)
只要你只使用方法上Any,而不是在执行运行时类型检查或用铸件isInstanceOf或asInstanceOf或模式匹配,有没有性能影响.
问题是你可以做很多事情,你可以做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)
}
Run Code Online (Sandbox Code Playgroud)
您回到了运行时类型检查的领域,这确实会对性能产生影响,但更重要的是会破坏您和其他人推理代码的能力.
所以,是的,如果你绝对肯定除了打电话toString你永远不需要做任何事情,你可以Any在这里使用.如果您正在编写惯用的Scala代码,这种情况不太可能经常出现,我个人建议明确地避免Any 在任何地方,包括在这种情况下.
更新:正如@pedrofurla在下面的评论中指出的那样,采用Int参数的方法和采用参数的方法之间存在一个重要的区别Any.在Any-taking方法中,整数参数将被加框,而它(不一定)在Int-taking方法中.
非常非常容易在Scala中意外地装箱原语(1.toString或者println(1)例如会这样做),并且一般来说,在基准测试或者探查器告诉你在特定情况下它是一个问题之前,你可能不应该担心.但这是避免Any参数的另一个原因,因为非泛型Int参数或带@specialized注释的泛型参数都不会导致不必要的装箱.