地图中的延迟评估

时间:2018-11-17 18:31:44

标签: scala

我正在尝试创建一个函数,该函数可以根据输入执行其他函数(返回Strings的函数。
例如:

def execute(input: String) = {
    val actions = Map("foo" -> someObject.doStuff(), "bar" -> someObject.doThing())
    actions.get(input) }

有没有一种方法可以使Map中的功能仅在相应键存在的情况下才能被调用?

3 个答案:

答案 0 :(得分:4)

object someObject {
  def doStuff() = "foo"
  def doThing() = "bar"

}

//if you need a string as a return value.
//there will be empty string for missing keys
def execute(input: String):String = {
  val actions = Map( "foo" -> someObject.doStuff _ ,
                     "bar" -> someObject.doThing _ )

  actions.getOrElse(input,()=>"")()
}


//if you need an Option[String] as a return value.
//there will be None value for missing keys
def executeOption(input: String):Option[String] = {
  val actions = Map( "foo" -> someObject.doStuff _ ,
                     "bar" -> someObject.doThing _ )

  actions.get(input).map(_())
}

答案 1 :(得分:1)

据我所知,您并不是真正在寻找␛[0;32mI (12633410) MQTT_CLIENT: Sending MQTT CONNECT message, type: 1, id: 0000␛[0m ␛[0;31mE (12633710) MQTT_CLIENT: Error network response␛[0m ␛[0;32mI (12633710) MQTT_CLIENT: Error MQTT Connected␛[0m ␛[0;32mI (12633710) MQTT_CLIENT: Reconnect after 10000 ms␛[0m ␛[0;32mI (12633710) MQTT_SAMPLE: MQTT_EVENT_DISCONNECTED␛[0m 。您正在尝试构建某种执行引擎,该引擎基于字符串输入执行某些操作。

现在,实现此目标的简单技巧是在2018-11-17 03:50:53: New connection from 73.94.66.49 on port 10793. 2018-11-17 03:50:53: Invalid protocol "MQIs�" in CONNECT from 73.94.66.49. 2018-11-17 03:50:53: Socket error on client <unknown>, disconnecting. 2018-11-17 03:51:20: New connection from 73.94.66.49 on port 10793. 中包含一个实际的lazy map并为输入字符串执行相应的功能。

所以,假设您有一个对象A,

functions

您想构建一个执行器,以执行输入Map的{​​{1}}和输入object A { var i = 1 def doFirstThing(): Unit = { i = i + 1 println(s"first thing :: $i") } def doSecondThing(): Unit = { i = i - 1 println(s"second thing :: $i") } } 的{​​{1}}。

因此,现在您需要创建doFirstThing "first"doSecondThing,它们将执行"second"functions

实际上很简单,

f1

或者,您可以使用f2A.doFirstThing()A.doSecondThing())转换为函数,

scala> val f1 = () => A.doFirstThing()
// f1: () => Unit = $$Lambda$1235/1187572055@7e192338

scala> val f2 = () => A.doSecondThing()
// f2: () => Unit = $$Lambda$1236/1696761182@47df3efe

现在,您可以使用这些地图来定义地图了,

_

它将完全忽略所有其他输入,

def

答案 2 :(得分:1)

是的,有一种方法可以在Map内部执行对象方法。但是您首先必须将函数放入地图。您所做的就是将对象方法的结果放入地图中。因此,您的方法已执行,其结果作为值放入映射中。

假设您的方法在此类中定义:

class SomeObject {
  def doStuff(): String = "I did stuff"
  def doThing(): String = "I did a thing"
}

您有该类的一个实例:

val someObject = new SomeObject

第一种方法是延迟执行这些方法的方法是使用lambda创建新函数并在这些lambda中执行方法:

val actions = Map(
  "foo" -> (() => someObject.doStuff()),
  "bar" -> (() => someObject.doThing()),
)

您可以使用特殊语法将对象方法直接转换为lambda:

val actions = Map(
  "foo" -> someObject.doStuff _,
  "bar" -> someObject.doThing _
)

如果您明确指定地图类型,那么也可以去除下划线:

val actions: Map[String, () => String] = Map(
  "foo" -> someObject.doStuff,
  "bar" -> someObject.doThing
)

接下来,您需要从地图上获取功能。如果该键没有任何功能,则使用默认功能-始终返回None

的默认功能。
val action = actions.getOrElse(input, () => None)

最后,您调用动作:

action()