2013-06-12 21 views
5

Scala'da bir hizmeti Verilen: isScala/Java birlikte çalışabilirliği: Int/Long (ilkel türler) içeren seçenekler nasıl ele alınır?

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

Java dan kullanılmak üzere:

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 
     } 

    } 
} 

Ben farklı bir şekilde ilkel ve temel olmayan türlerini tedavi etmek önlemek istiyorum.

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

ama bu yöntem için farklı bir ad gerektirir:

Yani başka bir yöntemi ekleyerek bu sorunu almaya çalıştı. Arayanın bakış açısından kafa karıştırıcı olabileceğinden, başka olasılıklar var mı?

Ben metod imzası biraz da kafa karıştırıcı olacağını Scala 2.10.1 ve Java 1.6

cevap

2

Ben sınamak için gidiyorum çözüm DummyImplicit kullanmaktır, bu yüzden Scala ve Java yöntemiyle her ikisi için aynı yöntem adı olabilir:

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)) 
    } 

böyle Scala kullanılacak:

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

ve Java dan : önerileriniz için

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

kullanıyorum, ancak çeşitli işlemek için eşleşen deseni kullanabilirsiniz - gibi bir şey:

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) 
    } 
    } 
} 

Ayrıca, java'dan çağrı yaptığınızdan emin değilim, ancak java.lang.Integer ile Int arasındaki örtük bir dönüşüm de işe yarayabilir?

+0

teşekkürler. Her ikisi de Int/Integer ile her iki yöntemi (Java için bir tane Scala için) açığa çıkarmak isterim. Birçok servis fonksiyonu olduğu için, kısa olmalıdır. “Kapalı” parametrelere gelince, AFAIK, Java'ya açıkça eklenmelidir. Muhtemelen sadece çok fazla gereksinimleri var :-) – Beryllium