【问题标题】:Scala: break outer function from inner functionScala:从内部函数中分离外部函数
【发布时间】:2013-10-04 15:21:45
【问题描述】:

我有什么

我下面有一个函数(我不能改变外部函数)

def outer(x: Int, inner: Int => Boolean): Boolean = {
    inner(x)
    false
} 

我想要什么

定义 inner 函数的方式是: if (x == 10) outer function return true

def inner(x: Int): Boolean = {
  if (x == 10) OUTER_FUNCTION_SHOULD_RETURN_TRUE!!!
  else false
}

outer(10, inner) // TRUE!!

问题

我该怎么做?

编辑:

我使用下一个技巧:

// If inner return true at least once, then outerWraper return true
def outerWrapper(x: Int, inner: Int => Boolean): Boolean = {
  var flag = false

  def inner2(e: Int): Boolean = {     
    if (!flag) flag = inner(e)
    inner(e)
  }

  outer(x, p2)  
  flag
}

我可以避免使用 var 标志,而是使用 val insted 吗?据我了解 var 在 Scala 中是一种不好的风格

【问题讨论】:

  • 据我所知,如果不更改 outer 函数,您将无法做到这一点!
  • 还有,不应该是outer(10,inner) // TRUE!!吗?
  • 首先,这看起来像是 Coursera 课程的家庭作业,因此不适合为您提供完整的解决方案。也就是说,作为编写exists 的提示(如果我正确理解这个问题,最终你会遇到什么问题):不要重复使用forall - 你只需要检查集合中的条目,直到找到匹配项,所以编写一个尾递归内部方法,以这种方式工作。
  • 进一步提示:假设您正在寻找偶数 - 如果集合中没有偶数,那么集合的所有元素必须是什么?您应该会发现,exists 的最简单解决方案实际上是单线。
  • 另外,可以在函数内部使用 vars。您只是不想将它们泄漏到函数或类的外部。您只需要确保您了解应用程序的其余部分是否存在泄漏。仅在本地和需要时使用 mutable。

标签: scala


【解决方案1】:

在 Scala 中,除非您使用 return 关键字,否则将返回最后一个表达式。在您的情况下,函数 outer 始终返回 false

由于您只是包装了内部函数,因此您可以删除 false:

def outer(x: Int, inner: Int => Boolean): Boolean = {
  inner(x)
}

def inner(x: Int): Boolean = {
  if (x == 10) true else false
}

或者,甚至更短:

def inner(x: Int): Boolean = {
  x == 10
}

这将返回内部函数的返回表达式,即true如果x == 10,否则false

【讨论】:

  • 我知道,但是我不能chanhe外部函数
  • 如果另一个函数看起来真的像你发布的那个,那么它总是会返回 false,因为最后一个表达式 (false) 被返回。您对此无能为力。
  • 我可以避免使用 var,而是使用 val 吗?
【解决方案2】:

如果你可以定义你的包装器,你可能可以避免使用var

def outerWrapper(x: Int, f: Int => Boolean): Boolean = {
    if (f(x)) true
    else outer(x, f)
}

然后你可以将inner方法传递给outerWrapper方法

outerWrapper(10,inner)

【讨论】:

    【解决方案3】:

    我的方法在这里:

    import scala.util.control.Breaks
    def outer(x: Int, inner: Int => Boolean): Boolean = {
      Breaks.breakable {
        inner(x)
        return false
      }
      true
    }
    
    def inner(x: Int): Boolean = {
      if (x == 10) Breaks.break()
      else false
    }
    
    println(outer(10, inner)) // TRUE!!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-12
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2014-10-01
      相关资源
      最近更新 更多