def m(x: Int): Any = { }
var set = new HashSet[Int => Any]
set += m
set += m
set.size
现在为2,set.contains(m)
为false,因为显然m
部分应用了两次,并且创建了两个函数对象。如果m
是一个函数,它将按预期工作。如果它们引用相同的方法,我想将函数视为等于。可以这样做吗? (不转向带有键返回的地图以便移除或传递其他中间变量)
答案 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"