如何将方法放入集合中?

时间:2011-07-04 11:46:02

标签: scala

def m(x: Int): Any = { }
var set = new HashSet[Int => Any] 
set += m
set += m

set.size现在为2,set.contains(m)为false,因为显然m部分应用了两次,并且创建了两个函数对象。如果m是一个函数,它将按预期工作。如果它们引用相同的方法,我想将函数视为等于。可以这样做吗? (不转向带有键返回的地图以便移除或传递其他中间变量)

2 个答案:

答案 0 :(得分:9)

在添加方法之前,使用val fun = m _将方法转换为函数。

执行set += m隐式创建一个新函数,该函数不等于执行set.contains(m)时创建的函数,例如在函数上下文中使用m都会创建一个全新且因此不同的函数对象。 (对不起,我刚看到,你已经说过了。)

这没关系,如果您只是需要以某种方式将方法放入集合中,然后将该集合用于所有引用。所以以下工作也是如此:

def m(x: Int): Any = { }
var set = new HashSet[Int => Any]
set += m
val fun = set.head // should not use head in real code but an iterator
set.contains(fun)

<强>加成

  

或传递其他中间变量

Scala中没有方法对象这样的东西。所以除非你比较他们的名字,否则我认为不可能比较两种方法。 (可能有可能使用反射,但我不确定这一点,并且它也是非常讨厌的 - 你不会有一组函数,但你需要转换为正确的方法的方法引用又回来了。)

答案 1 :(得分:1)

您可以将方法包装到具有相同签名的lambda中:

val m1 = (i:Int) => m(i)
set += m1
set += m1
println( set.size ) // Outputs "1"
println( set contains m1 ) //Outputs "true"