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

set.size jest teraz 2 i set.contains(m) jest fałszywa, ponieważ najwyraźniej m jest częściowo stosowana dwa razy i dwa obiekty funkcja jest tworzony. Jeśli m jest funkcją, działa zgodnie z oczekiwaniami. Chcę traktować funkcje jako równe, jeśli odwołują się do tej samej metody. Czy można to zrobić? (Bez włączania do map z kluczem zamian za usunięcie lub przechodząc wokół innych zmiennych pośrednich)Jak umieścić metody w zestawach?

Odpowiedz

9

użytkowania val fun = m _ przekształcić sposobem w funkcja przed dodaniem.

Wykonanie set += m niejawnie tworzy nową funkcję, która nie jest równa funkcji utworzonej podczas wykonywania set.contains(m), np. oba zastosowania m w kontekście funkcji tworzą całkowicie nowy, a tym samym inny obiekt funkcji. (Przepraszam, właśnie zobaczyłem, już to powiedziałeś.)

To jest w porządku, jeśli potrzebujesz tylko dostać metody do zestawu jakoś, a następnie użyj zestawu dla wszystkich odniesień. Więc następujące prace, a także:

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) 

Dodatek:

lub przechodzące wokół innych zmiennych pośrednich

Nie ma czegoś takiego jak metoda obiektu w Scala. Nie sądzę, że możliwe jest porównanie dwóch metod, chyba że porówna się ich nazwę. (Być może będzie to możliwe za pomocą refleksji, ale nie jestem do końca pewny i byłoby to całkiem nieprzyjemne - nie miałbyś zestawu funkcji, a jedynie referencji metod, które musiałbyś zmienić na odpowiednie metody i ponownie.)

1

Można owinąć metodę do lambda z tym samym podpisem:

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