Может ли Scala автоматически передавать параметры в следующем примере? - PullRequest
3 голосов
/ 17 августа 2011

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

for (security <- allSecurities) {
  val askLast = ask
}

Проблема в том, что я хотел бы, чтобы "ask" автоматически передавался "security". Моя попытка сделать это в родительском классе выглядит следующим образом

 var lastSecurity = ""  
  private val lastAsk = new HashMap[...]
  def allSecurities = for {
    security <- lastTrade.keySet.toList
  } yield {
    lastSecurity = security
    security
  }

  def ask = lastAsk(lastSecurity).price

К сожалению, это не совсем работает, как я и предполагал, поскольку в клиенте lastSecurity имеет одно и то же значение во всем цикле, а не динамически обновляется. Поэтому в основном я пытаюсь разрешить клиентам делать

val askLast = ask

вместо

val askLast = ask(security)

Могу ли я сделать это в Scala?

Ответы [ 3 ]

3 голосов
/ 17 августа 2011

Вы можете получить то, что хотите, с ленивым «просмотром» последовательности,

  var lastSecurity: Int = _
  val securities = Seq(1, 2).view.map { a => 
    lastSecurity = a
    a
  }

  for (s <- securities) {
    println("%d %d".format(s, lastSecurity))
  }

печать

1 1
2 2

Ключевая идея здесь заключается в том, что в режиме отложенного просмотра map вычисляется не сразу, а только как элементы, необходимые для цикла for.


Вот другой подход. Я не рекомендую это как хороший код, но он демонстрирует гибкость Scala,

  var lastSecurity: Int = _

  class SecurityWrapper(s: Seq[Int]) {
    def foreach(f: Int => Unit) {
      s.foreach { a =>
        lastSecurity = a
        f(a)
      }
    }
  }

  for (security <- new SecurityWrapper(Seq(1, 2))) {
    println("%d %d".format(security, lastSecurity))
  }

Класс SecurityWrapper содержит пользовательский метод foreach. На каждой итерации цикла он записывает в переменную lastSecurity. for сахар понимания Scala будет автоматически использовать SecurityWrapper.foreach без какой-либо дополнительной работы с нашей стороны.

0 голосов
/ 17 августа 2011

Вот что-то близкое, что позволяет клиентам не передавать аргумент для запроса.Вы можете изменить метод allSecurities, чтобы получить кортеж, содержащий защиту и значение, которое будет возвращено вызовом ask, то есть

def allSecurities = for {
  security <- lastTrade.keySet.toList
} yield {
  (security, lastAsk(security).price)
}

. Таким образом, клиенты могут писать

for((security,askLast)<-allSecurities){
  //to client things with askLast
}
0 голосов
/ 17 августа 2011

почему бы не создать список цен в родительском классе и использовать его в клиенте?

def myfunc = for(security <- allSecurities) yield {       
  lastAsk(security).price
} 

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

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