【问题标题】:What does func( arg: (type1, type2) => Future[Any]) mean in Scala?func( arg: (type1, type2) => Future[Any]) 在 Scala 中是什么意思?
【发布时间】:2020-08-24 05:32:49
【问题描述】:

我在 Scala 中遇到了一些代码,例如:

 def props(factory: (TransactionId,
                      String,
                      ImageName,
                      Boolean,
                      ByteSize,
                      Int,
                      Option[ExecutableWhiskAction]) => Future[Container])

具有多种数据类型的参数factory 意味着什么,Scala 的这个属性的名称或定义是什么,它是如何工作的?

【问题讨论】:

  • 这只是一个函数,它是一个非常基本的概念,我建议您遵循该语言的任何基本教程。
  • props 是一个以另一个函数 (factory) 作为参数的函数。 factory 本身是一个函数,其中包含在返回 Future[Container] 的参数元组中给出的类型参数。然后,您可以在 props 中调用 factory,就像调用任何其他函数一样。
  • @HristoIliev 实际上props 是一个接收函数方法
  • @DmytroMitin 我觉得将factory 的输入称为单个元组可能会使OP 感到困惑。这真的是一个 Function7 接受 7 个不同的参数并返回一个 Future

标签: scala higher-order-functions


【解决方案1】:
def props(factory: (TransactionId,
                    String,
                    ImageName,
                    Boolean,
                    ByteSize,
                    Int,
                    Option[ExecutableWhiskAction]) => Future[Container])

让我们从外向内解开这个定义。

def props(x: A) 定义了一个名为props 的函数或方法(取决于特定的上下文),它采用A 类型的参数x。在这种情况下,由于没有定义结果类型(我们没有def props(x: A): B),结果类型由编译器推断。

然后我们可以展开:

  • xfactory。参数绑定到factory
  • A(TransactionId, String, ImageName, Boolean, ByteSize, Int, Option[ExecutableWhiskAction]) => Future[Container]

factory 是一个和其他值一样的值。在这种情况下,(TransactionId, String, ImageName, Boolean, ByteSize, Int, Option[ExecutableWhiskAction]) => Future[Container] 只是另一种说法(这种翻译由编译器执行):

Function7[TransactionId, String, ImageName, Boolean, ByteSize, Int, Option[ExecutableWhiskAction], Future[Container]]

任何属于这种类型实例的对象都可以传递给props。这种类型只有一种感兴趣的方法:

def apply(x1: TransactionId,
          x2: String,
          x3: ImageName,
          x4: Boolean,
          x5: ByteSize,
          x6: Int,
          x7: Option[ExecutableWhiskAction]): Future[Container]

这个类型代表的是一个来自给定类型的 7 个参数的函数(为了简洁起见,我不会再次命名它们),结果是 Future[Container]

简而言之,我们有一个函数/方法(就我们的目的而言,这里没有区别,给出的代码并没有说明我们是在处理函数还是方法),它将函数作为参数。这使它成为一个高阶函数:在像 Scala 这样的语言中,函数是“一等”值,例如 Int,高阶函数的使用几乎是无限的。

在这种情况下,这基本上意味着props 函数/方法(或它委托给的一些其他函数/方法)有一些方法可以获取TransactionIdStringImageNameBooleanByteSizeIntOption[ExecutableWhiskAction] 和您,props 的调用者可以提供一种方法来获取您从这些值中选择的Future[Container]props 将(如果它决定:就像任何函数一样,props 可以决定(例如,如果某处有错误)不使用您传递给它的参数)如果它需要 Future[Container],则使用它。

如何创建Function7

  • 您可以显式扩展它:
val x: Function7[...] = new Function7 {
  def apply(...): ... = ???
}

object MyFactory extends Function7[...] {
  def apply(...): ... = ???
}
  • 在许多情况下更惯用的是,您可以使用 lambda 表达式,编译器会将其转换为与上述代码的第一位非常相似的内容:
{ (x1: TransactionId, x2: String, x3: ImageName, x4: Boolean, x5: ByteSize, x6: Int, x7: Option[ExecutableWhiskAction]) =>
  // some code that results in a `Future[Container]`
}
  • 如果您有一些 foo 对象,该对象具有 bar 方法,该方法采用适当的参数并具有适当的结果
foo.bar _

【讨论】:

  • “定义一个函数或方法(取决于特定的上下文)” def 总是创建一个方法,句号。
  • Odersky 等人不同意您的观点:Scala 编程(第 3 版),第 3 页。 28:“函数定义以def开头”。页。 143,同时将方法定义为定义为某个对象的成员的函数(在语言级别,而不是在实现级别)。
  • 该语言非常努力地使 functionsmethods 相同,但它们在 Scala 2 中是如此不同,因此需要加以区分 (希望 Scala 3 将减少这种差异,直到唯一相关的差异是实现细节)。我认为内部 def方法私有方法 (我知道这不是一个正式术语)因为它们仍然不是值,它们可以有参数的默认值,它们可以是通用的;函数具有所有相反的特征。
  • 你可以随心所欲地使用特殊定义,但在这种情况下你有点丧失了说“句号”的权利。
  • 我不在的时候你不必粗鲁。 Scala 中的 函数FunctionN 类之一的实例,def 不这样做。 - 是的,我知道函数这个词在编程上下文中被重载,这就是为什么在 Scala 中做出区分非常重要。
【解决方案2】:

好的,我想我现在明白了。正如 LuisMiguelMejíaSuárez 所说,props 将函数作为输入。经过进一步探索,我发现factory 只不过是props 作为输入的Lambda 函数的模板。谢谢大家

【讨论】:

  • lambda x => f(x) 不应与函数类型 X => Y ("This is not a pipe") 混淆。 X => Y 不是 x => f(x) 的“模板”。只是 Scala 使用相同的符号 =>,它们可能不同:x :=> f(x)X =>: Y。一个 lambda x => f(x) 有一个类型 X => Y 但类型 X => Y 不仅包含 lambda 项 x => f(x)
猜你喜欢
  • 2012-11-08
  • 2011-08-27
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多