Как вызвать функцию из hashmap в Scala - PullRequest
4 голосов
/ 16 ноября 2011

Я довольно новичок в scala, и в основном я хочу, чтобы пара функций была связана со строкой в ​​hashmap. Тем не менее я получаю сообщение об ошибке на подписчики. E.key (e.EventArgs); Заявление Option [EventArgs => Unit] не принимает параметры ... Пример кода:

object Monitor {
    val subscribers = HashMap.empty[String, (EventArgs) => Unit ]

    def trigger(e : Event){
      subscribers.get(e.key)(e.EventArgs);

    }

    def subscribe(key: String, e: (EventArgs) => Unit) {
      subscribers += key -> e;
    }

}

Ответы [ 4 ]

5 голосов
/ 16 ноября 2011

Метод get для Map дает вам Option значения, а не значения. Таким образом, если ключ найден на карте, вы получите Some(value), если нет, вы получите None. Поэтому вам нужно сначала «развернуть» эту опцию, чтобы убедиться, что на самом деле есть значение функции, которую вы можете вызвать (вызов apply on):

def trigger(e: Event): Unit =
  subscribers.get(e.key).foreach(_.apply(e.EventArgs))

или

def trigger(e: Event): Unit =
  subscribers.get(e.key) match {
    case Some(value) => value(e.EventArgs)
    case None =>
  }

Существует множество постов, объясняющих тип Option в Scala. Например этот или этот .

Также обратите внимание Замечание Луиджи об использовании неизменяемой карты (по умолчанию Map) с var вместо.

3 голосов
/ 16 ноября 2011

Поскольку метод get возвращает Option, вы можете использовать 'map' для этого:

subscribers.get(e.key).map(f => f(e.EventArgs))

или даже короче:

subscribers.get(e.key) map (_(e.EventArgs))
1 голос
/ 16 ноября 2011

get принимает только один аргумент.Таким образом, subscribers.get(e.key) возвращает параметр, а вы пытаетесь передать (e.EventArgs) в метод этого параметра apply (который не существует).

Также попробуйте сделать subscribers a var (или выбор изменяемого типа коллекции).На данный момент у вас есть неизменяемая коллекция и неизменяемая переменная, поэтому ваша карта не может измениться.Более идиоматический способ объявить это будет

var subscribers = Map[String, EventArgs => Unit]()
0 голосов
/ 16 ноября 2011

HashMap.get() в Scala работает несколько иначе, чем в Java.Вместо того, чтобы возвращать само значение, get() возвращает Option.Опция - это специальный тип, который может иметь 2 значения - Some(x) и None.В первом случае он говорит: "есть некоторое значение с таким ключом на карте".Во втором случае он говорит: «Нет, для этого ключа на карте нет ничего ( нет )».Это сделано для того, чтобы заставить программистов проверять, действительно ли карта имеет объект или нет, и избегать NullPointerException, что часто встречается в коде Java.

Итак, вам нужно что-то вроде этого:

def trigger(e: Event) {
  val value = subscribers.get(e.key)
  value match {
    case None => throw new Exception("Oops, no such subscriber...")
    case Some(f) => f(e.EventArgs)
  }
}

Более подробную информацию о Option сопоставлении типов и шаблонов можно найти в Scala здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...