2

私はscalaの初心者で、ここで何が起こったのか理解できません:

与えられた:

val reverse:Option[MyObject] = ...

ブールmyObject.isNaire値を返します。

私が行った場合 :

val v:Option[Boolean] =  reverse.map(_.isNaire)
val b:Boolean = v.getOrElse(false)

それは動作します。

今、もし私がするなら:

val b:Boolean = reverse.map(_.isNaire).getOrElse(false)

でコンパイルに失敗しますtype mismatch: found Any, required Boolean


編集 : ベリリウムに感謝します。SSCCE を作成することで、説明の始まりを見つけました。最初の例では、myObject は Java クラスなので、isNaire は java.lang.Boolean です。暗黙の変換はこれを透過的にするべきだと思ったので、説明はまだ歓迎されています。

class Test(val naire:java.lang.Boolean)

class Other {
  val testValue = Some(new Test(true))
  def mysteriousCompilationError:Boolean = testValue.map(_.naire).getOrElse(false)
}

注: ScalaCompiler は 2.10.2 です。

4

2 に答える 2

0

java.lang.Booleanscala.Boolean同じではありません。ギャップを埋めるには、暗黙的な変換が機能する場所を提供する必要があります。

これらのタイプの Java/Scala 相互運用性の問題を処理するには、いくつかのパターンがあります。


  • Scala 側から別のメソッドを使用しても問題ない場合は、暗黙の値クラスを使用できます。
object Container {
  implicit class Test2Scala(val test: Test) extends AnyVal {
    def naireForScala: Boolean = test.naire
  }
}

class Other {
  val testValue = Some(new Test(true))

  import Container._
  def mysteriousCompilationError: Boolean = 
    testValue.map(_.naireForScala).getOrElse(false)
}

これにより、実行時に追加のインスタンスは必要ありません。Java クラスを強化する別の方法を提供するだけです。


  • サブクラスを派生できる場合は、次を使用してメソッドの名前を保持できますDummyImplicit
class Test2(_naire: Boolean) extends Test(_naire) {
  def naire(implicit di: DummyImplicit): Boolean = _naire
}

class Other {
  val testValue = Some(new Test2(true))
  def mysteriousCompilationError: Boolean = 
    testValue.map(_.naire).getOrElse(false)
}

DummyImplicit、別のメソッド シグネチャを取得するために必要です。少しトリッキーで、実行時に追加のインスタンスが必要Test2ですが、Test(OOP に関して) です。


  • Java インスタンスを Scala インスタンスにラップします。
class TestWrapper(test: Test) {
  def naire: Boolean = test.naire
}

class Other {
  val testValue = Some(new TestWrapper(new Test(true)))

  def mysteriousCompilationError: Boolean = 
    testValue.map(_.naire).getOrElse(false)
}

追加のインスタンスが必要です。デリゲートを追加する必要があります。これは でTestWrapperはありませんがTest、単純です。

于 2013-08-04T21:13:36.813 に答える