Как положить методы в наборы? - PullRequest
8 голосов
/ 04 июля 2011
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 ]

9 голосов
/ 04 июля 2011

Используйте 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 голос
/ 04 июля 2011

Вы можете заключить метод в лямбду с такой же сигнатурой:

val m1 = (i:Int) => m(i)
set += m1
set += m1
println( set.size ) // Outputs "1"
println( set contains m1 ) //Outputs "true"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...