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

壊れやすいものを使用したい場合は、次のようにする必要があります。

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内から-基本的にand以外のもの)は、実際にはスタックレス例外をスローします。捕らえられた場合とメソッドによって捕らえられた場合。スタックトレースの作成は本当に遅いですが、スタックレス例外でさえ少し遅いです。forifwhilematchbreakbreakablereturn

したがって、正しい収集方法exists(この場合)を使用することが最善の解決策です。

于 2013-01-15T18:24:46.243 に答える
1

一般的なことしか言えませんが、少しでも参考になれば幸いです...

残念ながら、あなたのサンプル コードには無料の識別子が含まれているため、推測と仮定なしではその動作を理解することはできません。

あなたは問題について間違って考えています。ここで何をしているの?findコレクションの要素を ing しています。図書館を使おう!あらゆる種類の既製品があります。

それを扱うことになるとOption[Something]、好ましいアプローチはそれをmap超えることです。の場合NoneNoneアウトになります。その場合、Some(thing)渡した関数mapが適用されthing、結果は になりますSome(what-your-function-returned-for-thing)

または、Scala を初めて使用する人がより好みに合うことが多い方法として、 でパターン マッチングを使用して、ケースとケースOptionを効果的に区別することができます。NoneSome(thing)

Java ライブラリを扱う場合は、Java コレクションとの間の変換をコードのごく周辺にプッシュし、コードの大部分をネイティブの Scala コレクションを使用して慣用的な Scala に保つのが最善です。

同じことがnullJava からの s にも当てはまります。Optionできるだけ早い時期にそれらをオンにします。便宜上、Option(thing)ファクトリは athingを にnull変換しNone、非をラップnull thingします。Some

補遺

要するに、このコードでこれらの制御フロー メカニズムを使用するべきではありません。それらはすべて ( 以外のreturn) 例外に基づいており、関数型プログラミングの使用に重点を置いている Scala とは相容れないものです。このライブラリは、目的の本質的なロジックのクリーンで簡潔で効率的な実装をサポートしています。このような流れに逆らわないでください。

于 2013-01-15T18:10:08.880 に答える
1

問題は、役割を見つけたときに scala.util.control.Breaks.break が正しい方法で戻るかどうかです。私には正しく見えません。

の最初のインスタンスを探しているだけなので、正確にそれを行い、これを行う慣用的な方法をauthority.getAuthority == role使用できます。find

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

またはもっと簡潔に

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

これらは、存在する場合にOption値を取得できる型を返しますauthority

于 2013-01-15T17:48:27.433 に答える
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 に答える
0

return trueだけでなく、return false交換しないのはなぜhasRoleですか?

于 2013-01-15T17:47:45.210 に答える