2013-06-12 6 views
5

Scala/Javaの相互運用性:Int/Long(プリミティブ型)を含むオプションを扱う方法は?</p> <pre><code>class ScalaService { def process1(s: Option[String], i: Option[Int]) { println("1: " + s + ", " + i) } } </code></pre> <p>、Javaから使用される:Scalaではサービスを考える

public class Java { 
    public static void main(String[] args) { 
     ScalaService service = new ScalaService(); 

     // This works, but it's confusing 
     { 
      scala.Option<String> so = scala.Option.apply("Hello"); 
      scala.Option<Object> io = scala.Option.apply((Object) 10); 
      service.process1(so, io); 
     } 

     // Would be OK, but not really nice 
     { 
      scala.Option<Object> so = scala.Option.apply((Object) "Hello"); 
      scala.Option<Object> io = scala.Option.apply((Object) 10); 
      service.process1(so, io); // Does not compile 
     } 

     // The preferred way 
     { 
      scala.Option<String> so = scala.Option.apply("Hello"); 
      scala.Option<Integer> io = scala.Option.apply(10); 
      service.process1(so, io); // Does not compile 
     } 

    } 
} 

私は別の方法でプリミティブおよび非プリミティブ型を治療するために避けたいと思います。

def process2(s: Option[String], i: Option[java.lang.Integer]) { 
    print("2: ") 
    process1(s, i.map(v => v.toInt)) 
} 

をが、これはメソッドのために別の名前が必要です。

は、だから私は、別の方法を追加することでこれを回避しようとしました。 これは発信者の観点から混乱する可能性があるため、他の可能性はありますか?

私はメソッドのシグネチャは、ビットが同様に混乱だろうスカラ座2.10.1、およびJava 1.6

答えて

2

私がテストするつもりソリューションはDummyImplicitを使用することですので、私はスカラ座とJavaメソッドの両方に同じメソッド名を持つことができます。

class ScalaService { 
    // To be called from Scala 
    def process(s: Option[String], i: Option[Int])(implicit d: DummyImplicit) { 
    println("1: " + s + ", " + i) 
    } 

    // To be called from Java 
    def process(s: Option[String], i: Option[java.lang.Integer]) { 
    print("2: ") 
    process(s, i.map(v => v.toInt)) 
    } 

は次のようにScalaの中から使用する:

object ScalaService extends App { 
    val s = new ScalaService() 
    s.process(Some("Hello"), Some(123)) 
} 

とJavaから:

public class Java { 
    public static void main(String[] args) { 
     ScalaService service = new ScalaService(); 

     { 
      scala.Option<String> so = scala.Option.apply("Hello"); 
      scala.Option<Integer> io = scala.Option.apply(10); 
      service.process(so, io); 
     } 
    } 

} 
2

を使用していますが、あなたは、様々なタイプを処理するために、パターンマッチングを使用することができます - 何かのように:

class ScalaService { 
    def process1(s: Option[String], i: Option[Any]) { 
    i match { 
     case Some(i2:Int) => processInternal(s, Some(i2)) 
     case Some(i2:java.lang.Integer) => processInternal(s, Some(i2.intValue)) 
     case _ => processInternal(s, None) // or throw exception if you prefer 
    } 

    def processInternal(s:Option[String], i:Option[Int]) { 
     println("1: " + s + ", " + i) 
    } 
    } 
} 

また、Javaからの呼び出しについてはわかりませんが、おそらくjava.lang.Integerから暗黙の変換をIntにすることもできますか?

+0

ご提案いただきありがとうございます。私は両方のメソッド(1つはScala用、もう1つはJava用)、両方ともInt/Integerで公開したいと思います。多くのサービス機能があるので、それは不足しているはずです。暗黙のパラメータに関しては、AFAIKはJavaで明示的に追加されなければなりません。それはおそらくあまりにも多くの要件:-) – Beryllium

関連する問題