scala中的函数/方法引用相等

时间:2015-08-27 13:09:03

标签: scala

你好可以检查scala中的方法/函数引用是否等于另一个?例如,编写如下的函数并获得true?

scala> def m = 1
m: Int

scala> def check(p: () => Int): Boolean = p == m _
check: (p: () => Int)Boolean              

scala> check(m _)
res0: Boolean = false

1 个答案:

答案 0 :(得分:1)

<强>要点:
是的,可以测试Scala中两个具体函数引用之间的相等性,但不完全按照您说明问题的方式进行测试。您只需要捕获对象,类或特征(不是lambda,匿名函数等)的具体函数引用。

<强>详细信息:
因为Scala确实具有函数引用的概念,所以可以检查两个不同的函数引用以获得引用相等性。而且因为Scala还提供了一种从任何有效的Scala方法获取函数引用的机制,这意味着你可能会做你想要做的事情,因为你对mz的答案提出了评论问题,“...没有办法得到一个方法的参考或类似的东西?“

要记住的重要事项是只能检查两个函数的参考相等性。 IOW,对函数不能检查函数定义是否相等(对于Pandora的盒子,它不会产生不希望的不可判断的切线)。

所以,下面是我如何具体而准确地思考它。我使用IntelliJ(15.0.3)中的Scala(2.11.7)工作表来创建以下测试场景。

首先,失败途径,编译时间和运行时间:

object ConcreteMethods1 {
  def intToStringNone(string: String): Option[Int] =
    None

  def intToStringSome1(string: String): Option[Int] =
    Some(1)
}
//def someMethodFailureCompileTime(
//    parseFunctionReference: String => Option[Int]
//): (Boolean, Boolean) = {
//  (
//      parseFunctionReference == ConcreteMethods1.intToStringNone
//    , parseFunctionReference == ConcreteMethods1.intToStringSome1
//    )
//}
def someMethodFailureRuntime(
    parseFunctionReference: String => Option[Int]
): (Boolean, Boolean) = {
  val intToStringNoneFunctionReference: String => Option[Int] =
    ConcreteMethods1.intToStringNone
  val intToStringSome1FunctionReference: String => Option[Int] =
    ConcreteMethods1.intToStringSome1
  (
      parseFunctionReference == intToStringNoneFunctionReference
    , parseFunctionReference == intToStringSome1FunctionReference
  )
}
val someMethodNoneFailureRuntime =
  someMethodFailureRuntime(ConcreteMethods1.intToStringNone)
  //want (true, false), but get (false, false)
val someMethodSome1FailureRuntime =
  someMethodFailureRuntime(ConcreteMethods1.intToStringSome1)
  //want (false, true), but get (false, false)

第二,成功途径(这意味着编译时间和运行时间):

object ConcreteMethods2 {
  def intToStringNone(string: String): Option[Int] =
    None

  def intToStringSome1(string: String): Option[Int] =
    Some(1)

  val intToStringNoneFunctionReference: String => Option[Int] =
    intToStringNone

  val intToStringSome1FunctionReference: String => Option[Int] =
    intToStringSome1
}
def someMethodSuccess(
    parseFunctionReference: String => Option[Int]
): (Boolean, Boolean) = {
  (
      parseFunctionReference == ConcreteMethods2.intToStringNoneFunctionReference
    , parseFunctionReference == ConcreteMethods2.intToStringSome1FunctionReference
  )
}
val someMethodNoneSuccess =
  someMethodSuccess(ConcreteMethods2.intToStringNoneFunctionReference)
val someMethodSome1Success =
  someMethodSuccess(ConcreteMethods2.intToStringSome1FunctionReference)

你有它,测试Scala中两个具体函数引用之间的相等性。这个小技巧帮助解决了递归的核心问题我尝试编写通用解析代码,该代码从根文件串故障转移解析。我能够使用这个具体的函数引用相等技巧来正确地终止递归。