【问题标题】:Specifying the lambda return type in Scala在 Scala 中指定 lambda 返回类型
【发布时间】:2014-03-10 23:02:26
【问题描述】:

注意:这是一个理论上的问题,我不是试图解决任何问题,也不是为了实际目的而达到任何效果

在 Scala 中使用 (arguments)=>expression 语法创建 lambda 时,是否可以显式提供返回类型?

Lambdas 与方法没有什么不同,它们都被指定为表达式,但据我了解,方法的返回类型很容易使用 def name(arguments): return type = expression 语法定义。

考虑这个(说明性的)示例:

def sequence(start: Int, next: Int=>Int): ()=>Int = {
    var x: Int = start

    //How can I denote that this function should return an integer?    
    () => {
        var result: Int = x
        x = next(x)
        result
    }
}

【问题讨论】:

  • 您已经通过将() => Int 指定为sequence 的返回类型来完成此操作。这已经强制您返回的 lambda 必须符合该类型,并且编译器将尝试这样解释它。
  • @ghik 这只是一个不幸的例子......

标签: scala types lambda


【解决方案1】:

您始终可以通过附加: 和类型来声明表达式的类型。所以,例如:

((x: Int) => x.toString): (Int => String)

例如,如果您有一个大而复杂的表达式并且您不想依赖类型推断来直接获取类型,这将非常有用。

{
  if (foo(y)) x => Some(bar(x))
  else        x => None
}: (Int => Option[Bar])
// Without type ascription, need (x: Int)

但是如果将结果分配给具有指定类型的临时变量,可能会更清楚:

val fn: Int => Option[Bar] = {
  if (foo(y)) x => Some(bar(x))
  else        _ => None
}

【讨论】:

  • 这似乎就是我要找的东西!但是:这是编译时检查还是强制转换?
  • @yannbane 这是编译时检查,而不是强制转换。
  • 在 Scala 中,为了使任何函数递归,我们需要指定返回类型,从 2020.2.3 开始,IntelliJ 将无法自动建议返回类型,因此这个答案实际上很重要供 Scala 编码人员理解。
【解决方案2】:

假设你有这个功能:

def mulF(a: Int, b: Int): Long = {
      a.toLong * b
}

同样的函数可以写成带有定义输入和输出类型的 lambda:

val mulLambda: (Int, Int) => Long = (x: Int, y: Int) => { x.toLong * y }

【讨论】:

    【解决方案3】:
    x => x:SomeType
    

    我自己不知道答案,因为我从来不需要它,但我的直觉是这会奏效。并在工作表中尝试证实了这一点。

    编辑:我在上面有一个例子之前提供了这个答案。确实,在具体示例中不需要这样做。但在极少数情况下你需要它,我展示的语法会起作用。

    【讨论】:

    • 咳咳,你能用这个来造句吗? 开玩笑的,请看我的编辑。我是 Scala 新手,所以我不太明白如何整合您的答案。
    • 在您的示例中,您不需要指定它是一个 Int。因为 Int 已经是编译器推断的类型了。为什么要在这里明确指定它?你可以(写result:Int),但这不会有任何区别。
    • 是的,我选择了一个不幸的例子。但是让我们假设它是一个随机的 lambda,没有任何东西,没有被返回或任何东西......
    • 在 TypeScript 中我们就是这样做的,但是在 Scala 中,这不起作用,您需要将类型指定为返回值的函数,如上述接受的答案,或者不会编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2019-12-14
    相关资源
    最近更新 更多