如何在 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
How do you define a type for a function in Scala?
提问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.
如果你想用一些逻辑来包装你的异步函数参数,这可能会非常方便,例如类似事务的操作。

