2011-07-04 22 views
8
def m(x: Int): Any = { } 
var set = new HashSet[Int => Any] 
set += m 
set += m 

set.size es ahora 2, y set.contains(m) es falso, porque aparentemente m se aplica parcialmente dos veces y objetos es creado dos funciones. Si m es una función, funciona como se esperaba. Quiero tratar las funciones como iguales si hacen referencia al mismo método. Se puede hacer esto? (Sin volver a los mapas con la tecla de retorno para la eliminación, o pasando alrededor de otras variables intermedias)¿Cómo poner los métodos en conjuntos?

Respuesta

9

Uso val fun = m _ para transformar el método en una función antes de agregarlo.

Al hacer set += m implícitamente se crea una nueva función que no es igual a la función creada al hacer set.contains(m), p. ambos usos de m en un contexto de función crean un objeto de función completamente nuevo y por lo tanto diferente. (Lo siento, acabo de ver, ya lo has dicho).

Esto está bien, si solo necesitas obtener los métodos en el conjunto de alguna manera y luego usar el conjunto para todas las referencias. Por lo tanto, las siguientes obras: así

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) 

adición:

o que pasan alrededor de otras variables intermedias

No hay tal cosa como un método objeto en Scala. Así que no creo que sea posible comparar dos métodos a menos que compares su nombre. (Podría ser posible usar la reflexión, pero no estoy seguro de eso y sería bastante desagradable hacerlo también; no tendría entonces un conjunto de funciones sino de referencias de métodos que necesitaría transformar a métodos adecuados) y viceversa).

1

Usted puede envolver el método en una lambda con la misma firma:

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