在scala中的自定义控件结构中声明变量

时间:2013-03-20 03:19:51

标签: scala

我想知道是否有办法在自定义控件结构的参数列表中创建临时变量。

基本上,我想创建一个类似于的控件结构 for循环,我可以创建一个变量,i,并且只能在循环体中访问i:

for(i<- 1 to 100) {
   //loop body can access i here
}
//i is not visible outside

我想在我的代码中做类似的事情。例如,

customControl ( myVar <- "Task1") {
    computation(myVar)
}

customControl ( myVar <- "Task2") {
    computation(myVar)
}
def customControl (taskId:String) (  body: => Any) = {
    Futures.future {
        val result = body

        result match {
            case Some(x) =>
                logger.info("Executed successfully")
                x
            case _ =>
                logger.error(taskId + " failed")
                None
        }

    }
}

现在,我通过在自定义控件结构之外声明一个变量来解决这个问题,这看起来并不优雅。

val myVar = "Task1"
customControl {
    computation(myVar)
}

val myVar2 = "Task2"    
customControl {
    computation(myVar2 )
}

2 个答案:

答案 0 :(得分:2)

请注意,内置for (x <- expr) body只是

的语法糖
expr foreach (x => body)

因此,通过定义自定义for方法,可以实现您想要的(使用现有的foreach语法)。

另请注意,已存在适用于字符串的foreach方法。你可以这样做:

case class T(t: String) {
  def foreach(f: String => Unit): Unit = f(t)
}

注意:您还可以将上面f的结果类型从Unit更改为Any,它仍然有效。

这将使您能够执行类似

的操作
for (x <- T("test"))
  print(x)

这只是一个简单(无用)的例子,因为现在for (x <- T(y)) f(x)只是缩写(或者更确切地说是“enlongishes”)f(y)。但是,当然通过将f的上述foreach中的String的参数从t更改为其他内容并从字符串{{1}}执行相应的转换为此类型,可以实现更有用的效果。

答案 1 :(得分:2)

你可以这样做:

import scala.actors.Futures

def custom(t: String)(f: String => Any) = {
  Futures.future {
    val result = f(t)

    result match {
      case Some(x) =>
        println("Executed successfully")
        x
      case _ =>
        println(t + " failed")
        None
    }

  }
}

然后你可以得到这样的语法,这不是你要求的,但是你可以在一个单独的行上声明变量:

scala> custom("ss") { myvar => println("in custom " + myvar); myvar + "x" }
res7: scala.actors.Future[Any] = <function0>
in custom ss
ss failed

scala> custom("ss") { myvar => println("in custom " + myvar); Some(myvar + "x") }
in custom ss
Executed successfully
res8: scala.actors.Future[Any] = <function0>

scala>