Как определить более краткую функцию scala

#scala #akka #partialfunction

#scala #akka #частичная функция

Вопрос:

Я использую библиотеку akka и предоставляю частичную функцию, которая будет реализована субъектом во время выполнения с помощью горячей замены.

Горячая замена akka принимает аргумент в виде PartialFunction[Any, Unit] . Я определил свою как следующую:

 class Fake1Reader extends AbstractReader {

  def read: PartialFunction[Any, Unit] = {
    case readingRequest: ReadingRequest => {
      var reading: Reading = new ReadingImpl(readingRequest.getResourceId, "payload",
        Calendar.getInstance.getTime,
      readingRequest.getfrequency, readingRequest.getMappingName,
        readingRequest.getClassificationType,
      readingRequest.getReadingRequestId)
      sendConsumeMessage(reading)
    }
  }
}
  

итак, чтобы использовать эту функцию, я должен предоставить новый Fake1Reader().read .

Есть ли более краткий способ создания этого класса с использованием apply или extending Function или PartialFunction?

Комментарии:

1. Извините, я не понимаю проблемы. Не могли бы вы уточнить / уточнить?

2. Вы могли бы уменьшить это примерно на 30%, вызвав свою переменную r вместо readingRequest .

Ответ №1:

Если у AbstractReader вас нет состояния, вы можете определить object вместо class , чтобы избежать ненужного создания объекта при каждом использовании, и поместить свои функции там как неизменяемые val .

Кроме того, сопутствующий объект akka.actor.Actor определяет type Receive как псевдоним для PartialFunction[Any, Unit] , поэтому вы можете писать свои частичные функции следующим образом:

 package foo    
object Fake1Reader extends AbstractReader {
  import akka.actor.Actor._

  val read: Receive = { 
    case readingRequest: ReadingRequest => /* implementation */
  }
}
  

использование:

 import foo.Fake1Reader._

actorRef ! HotSwap(read)
  

Комментарии:

1. это для приложения с чрезвычайно высоким уровнем параллелизма, и я изначально определил его как объект с единственной функцией и переключил на класс. Я беспокоился о том, что многие участники обращаются к одному и тому же объекту.

2. На самом деле я ищу, чтобы определение класса действительно было функцией, не уверен, возможно ли это.

3. Если она неизменяема / не имеет состояния, то любое совместное использование не является проблемой. Если вы считаете, что у вас возникнут проблемы с производительностью, это может помочь на самом деле иметь один (или имитировать условия одного), а затем измерить фактические накладные расходы.

4. Вы можете определить функцию как класс, расширив PartialFunction[Any, Unit] и внедрив apply isDefinedAt методы and , но я не думаю, что это поможет улучшить читаемость вашего кода.

Ответ №2:

В качестве примечания, это уменьшает явную утомительность повторения:

 case readingRequest: ReadingRequest => {
  import readingRequest._
  var reading: Reading = new ReadingImpl(getResourceId, "payload",
    Calendar.getInstance.getTime,
  getfrequency, getMappingName,
    getClassificationType,
  getReadingRequestId)
  sendConsumeMessage(reading)
}