Scala 中的函数/方法引用相等性 [英] function/method reference equality in scala

查看:42
本文介绍了Scala 中的函数/方法引用相等性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,是否可以在 Scala 中检查一个方法/函数引用是否等于另一个?比如写一个类似下面的函数并得到true?

Hello is it possible to check if a method/function reference is equal to another in scala? For example to write a function like the following and get 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

推荐答案

总结:
是的,可以在 Scala 中测试两个具体函数引用之间的相等性,但不完全按照您陈述问题的方式.您只需要捕获对象、类或特征(而不是 lambda、匿名函数等)的具体函数引用.

Summary:
Yes, it is possible to test for equality between two concrete function references in Scala, but not exactly in the way you stated your problem. You just have to capture the concrete function reference of an object, class or trait (not a lambda, anonymous function, etc.).

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

Details:
Because Scala does have the notion of a function reference, it is possible to check two different function references for reference equality. And because Scala also provides a mechanism for obtaining a function reference from any valid Scala method, it means you can likely do what you were seeking to do, given your comment question on m-z's answer, "...there is no way to get a reference or something similar for a method?"

要记住的重要一点是,只能检查两个函数的引用相等性.IOW,不能检查函数的函数定义相等性(无论如何,对于它会生成的不想要的不可判定切线的潘多拉盒子,你并不真正想要它).

The essential thing to remember is that two functions can only be checked for reference equality. IOW, to functions CANNOT be checked for function definition equality (which you don't really want anyway for the Pandora's box of undesired undecidable tangents it would generate).

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

So, below is how I came to think about it concretely and accurately. I used the Scala (2.11.7) Worksheet within IntelliJ (15.0.3) to create the following test scenarios.

首先,失败路径,包括编译时间和运行时间:

First, the failure pathway, both compile time and run time:

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)

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

Second, the success pathway (which implies both compile time and run time):

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 中测试两个具体函数引用之间的相等性.这个小技巧帮助解决了递归的核心问题,我试图编写通用解析代码,该代码从根的字符串故障转移进行解析.我能够使用这个具体的函数引用相等技巧来正确终止递归.

And there you have it, testing equality between two concrete function references in Scala. This little trick helped solve a core issue with recursion I had trying to write generic parsing code which had a parsing from a string failover at root. I was able to use this concrete function reference equality trick to properly terminate the recursion.

这篇关于Scala 中的函数/方法引用相等性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆