【问题标题】:In Scala, how would you declare static data inside a function?在 Scala 中,如何在函数中声明静态数据?
【发布时间】:2013-05-16 02:47:29
【问题描述】:

在许多情况下,我发现我需要在函数的范围内创建长期存在的值,而这些数据不需要在类/对象范围内。

例如,

object Example {

   def activeUsers = {
       val users = getUsersFromDB  // Connects to the database and runs a query.
       users.filter(_.active)
   }
}

上面,变量users在正确的范围内,但是每次调用函数activeUsers时它都会执行一个数据库查询。

为避免这种情况,我可以将变量 users 移到函数范围之外:

object Example {
   val users = getUsersFromDB  // Connects to the database and runs a query

   def activeUsers = {
       users.filter(_.active)
   }
}

但这使它也可用于其他功能。

否则,我可以创建一个单独的对象来包含该函数:

object Example {

   object activeUsers {
       val users = getUsersFromDB  // Connects to the database and runs a query.

       def apply() = {
           users.filter(_.active)
       }
   }
}

但这涉及更多样板代码、使用另一个对象以及与apply 相关的轻微语法异常。

  • 在语言级别是否支持类似的内容?
  • 如果没有,您在这种情况下是否使用了任何标准技术?

【问题讨论】:

    标签: scala


    【解决方案1】:

    另一种选择是使用闭包:

    object Example {
       val activeUsers = {
           val users = getUsersFromDB
           () => users.filter(_.active)
       }
    }
    

    说明

    activeUsersFunction1[Unit, ...your filter result type...]类型的变量(或者我们可以把这个类型写成(Unit => ...your filter result type...),同理),也就是这个变量存储了一个函数。因此,您以后可能会以与功能无法区分的方式使用它,例如activeUsers()

    我们用一段代码初始化这个变量,我们声明变量users并在匿名函数() => users.filter(_.active)中使用它,因此它是一个闭包(因为它有一个绑定变量users)。

    因此,我们实现了您的目标:(1)activeUsers 看起来像一个方法; (2)users计算一次; (3) filter 在每次通话中都有效。

    【讨论】:

    • 正确。您可能想解释那里发生了什么,以及它为什么起作用。
    • 感谢您的解释。我仍然希望找到类似于 C 的“静态”变量的更甜美的语法。
    【解决方案2】:

    Extending FunctionXX 是实现目标的另一种方式;它可能具有提供更好文档的优势。参数类型和返回值类型都在声明的第一行可见:

    val activeUser = new Function0[List[String]] {
      val users = getUsersFromDB
      def apply = users filter (_.active)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 2011-07-08
      相关资源
      最近更新 更多