1

我有以下代码:

private def hasRole(role: String): Boolean = {
  var hasRole = false;
  if(getUserDetails.isDefined){

    // getAuthorities returns java.util.Collection<GrantedAuthority>
    val authorities: util.Collection[_ <:GrantedAuthority] = getUserDetails.get.getAuthorities
    // Wrap the collection is a Scala class 
    val authoritiesWrapper = JCollectionWrapper.apply(authorities);
    for(authority <- authoritiesWrapper.iterator){
      if(authority.getAuthority == role){
        hasRole = true;
        scala.util.control.Breaks.break  
      }
    }
  }
  hasRole
}

问题是,当我找到这个角色时scala.util.control.Breaks.break,正确的方法是什么?return在我看来不合适。

4

5 回答 5

9

如果你想使用breakable,你需要这样做:

import scala.util.control.Breaks._
breakable {
  for (i <- 0 to 10000) { if (i>3) break }
}

但是,如果您发现自己经常这样做,那么您可能没有充分利用收藏库。试试吧

authoritiesWrapper.iterator.exists(_.getAuthority == role)

此外,在您给出的示例中,您还可以

if (authority.getAuthority == role) return true

什么时候选哪个?一般来说,如果可以的话,您应该使用集合库中的控制流选项。它们通常是最快和最清晰的。等等,最快——这是为什么呢?两者breakand return(来自for需要闭包的或其他上下文 - 基本上除了ifand之外的任何while东西match)实际上都会抛出一个被捕获的无堆栈异常;在break它被方法捕获breakable的情况下,在return它被方法捕获的情况下。创建堆栈跟踪确实很慢,但即使是无堆栈异常也有点慢。

所以使用正确的收集方法——exists在这种情况下——是最好的解决方案。

于 2013-01-15T18:24:46.243 回答
1

问题是,当我找到角色时, scala.util.control.Breaks.break 是正确的返回方式吗?在我看来不合适。

由于您只是在寻找第一个实例,authority.getAuthority == role因此您可以使用findwhich 正是这样做的,并且是执行此操作的惯用方式。

authoritiesWrapper.iterator.find(authority => authority.getAuthority == role)

或更简洁地说

authoritiesWrapper.iterator.find(_.getAuthority == role)

这些返回一个类型,如果它存在Option,您可以从中获取值。authority

于 2013-01-15T17:48:27.433 回答
1

我只能为您提供一般性,但我希望它至少有点帮助......

不幸的是,您的示例代码包含免费标识符,因此我无法在没有猜测和假设的情况下理解它的作用。

你把问题想错了。你在这里做什么?你是find一个集合的元素。使用图书馆!它有各种现成的东西。

当涉及到处理时Option[Something],首选的方法是map克服它。如果它是一个None,你会得到一个None出局。如果是,Some(thing)那么您传递给的函数map将被应用于thing并且结果将是Some(what-your-function-returned-for-thing).

或者,对于 Scala 的新手来说,通常觉得更可口的是,您可以在 an 上使用模式匹配Option来有效地区分Nonecase 和Some(thing)case。

在处理 Java 库时,最好将 Java 集合之间的转换推送到代码的最外围,并使用原生 Scala 集合保留大部分代码惯用的 Scala。

null来自 Java的 s 也是如此。Option尽早将它们变成。为方便起见,工厂Option(thing)会将 a变成 a并将 non- 包裹在 athingnullNonenull thingSome

附录

结果是你真的不应该在这段代码中使用这些控制流机制。它们都基于异常(除了return),并且与 Scala 对使用函数式编程的强调不符。该库支持您尝试的基本逻辑的干净、简洁、高效的实现。不要像这样违背粮食。

于 2013-01-15T18:10:08.880 回答
0

为什么不return true只是return false替换hasRole

于 2013-01-15T17:47:45.210 回答
0

谢谢大家,基于@Rex Kerr 的回答,我现在有了这个:

private def hasRole(role: String): Boolean = {
  var hasRole: Boolean = false;
  if(getUserDetails.isDefined){
    val authorities: util.Collection[_ <:GrantedAuthority] = getUserDetails.get.getAuthorities
    val authoritiesWrapper = JCollectionWrapper.apply(authorities);
    hasRole = authoritiesWrapper.iterator.exists(_.getAuthority == role)
  }
  hasRole
}

看起来和感觉都不错。我exists用来查看集合中存在的角色,然后返回该结果。false如果用户未定义(未登录),则默认返回。

如果这仍然不完美,请发表评论。

于 2013-01-16T09:27:26.607 回答