如何在 Scala 中为函数定义类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1853868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:46:52  来源:igfitidea点击:

How do you define a type for a function in Scala?

scalafunction

提问by Alex Black

I'm hoping there is a way to define a type for a function in Scala.

我希望有一种方法可以在 Scala 中为函数定义类型。

For example, say I want a function that takes two Ints and returns a Boolean, I could define a function that uses that like this:

例如,假设我想要一个接受两个 Int 并返回一个布尔值的函数,我可以定义一个使用这样的函数:

def checkInts(f: (Int,Int) => Boolean) = {
  // do stuff
}

Is there a way to define the type of f? Then I could do something like:

有没有办法定义f的类型?然后我可以做这样的事情:

def checkInts(f: MyFunctionType)

or

或者

def checkInts(f: Option[MyFunctionType])

回答by Mitch Blevins

trait Foo {
  type MyFunction = (Int,Int) => Boolean

  def checkInts(f: MyFunction)
  def checkInts(f: Option[MyFunction])
}

回答by Vladimir Salin

To augment the original answer:

要增加原始答案:

For some more complex cases, you can go with structural types that could also include function definitions [1], [2].

对于一些更复杂的情况,您可以使用还可以包含函数定义[1][2] 的结构类型。

As for particular examples and practical usage, function types could be used quite nicely with Futures, e.g. to pass an ExecutionContextand actually execute an async function after you pass it.

至于具体的例子和实际用法,函数类型可以很好地与Futures一起使用,例如传递一个ExecutionContext并在传递它之后实际执行一个异步函数。

Note, however, if you always have your EC available in the executing class and therefore you have no need to pass it, you could go with by-name arguments ("gimme just a Futureresult") [3].

但是请注意,如果您的 EC 在执行类中始终可用,因此您无需传递它,您可以使用按名称参数(“给我一个Future结果”)[3]

A draft example below shows this simple idea: it has a function type just with the ecand a structural type that could also take some parameters for the function to be executed. It also shows an alternative with by-name function:

下面的一个草稿示例展示了这个简单的想法:它有一个函数类型ec和一个结构类型,它也可以为要执行的函数带一些参数。它还显示了按名称功能的替代方案:

/** Define types in companion and sample functions that use them as args. */
class Fun(implicit ec: ExecutionContext) {
  import Fun._

  def foo(fun: SimplyFun): Future[String] = fun()
  def bar(fun: StructuredFun): Future[String] = fun.buzz(fun.bee)
  def byNameBaz(fun: => Future[String]) = fun
}

object Fun {
  type SimplyFun = ExecutionContext => Future[String]
  type StructuredFun = {
    def buzz(bee: Int)(implicit ec: ExecutionContext): Future[String]
    val bee: Int
  }
}

// (somewhere outside)
// example args could be instantiated as follows:
val simpleArg: SimplyFun = _ => Future.successful(String)
val structuredArg: StructuredFun = new {
  def buzz(bee: Int)(implicit ec: ExecutionContext) = Future.successful(s"$bee")
  val bee = 3
}

// ...and passed for execution along with the EC you like:
import scala.concurrent.ExecutionContext.Implicits.global
new Fun().foo(simpleArg)
new Fun().bar(structuredArg)
new Fun().byNameBaz(Future.failure(new RuntimeException))

This might be very handy if you want to wrap your async function argument with some logic around, e.g. transaction-like operations.

如果你想用一些逻辑来包装你的异步函数参数,这可能会非常方便,例如类似事务的操作。