2010-01-13 16 views

cevap

25

Sen Java yansıması ile yapabilirsiniz

case class Caller[T>:Null<:AnyRef](klass:T) { 
    def call(methodName:String,args:AnyRef*):AnyRef = { 
    def argtypes = args.map(_.getClass) 
    def method = klass.getClass.getMethod(methodName, argtypes: _*) 
    method.invoke(klass,args: _*) 
    } 
} 
implicit def anyref2callable[T>:Null<:AnyRef](klass:T):Caller[T] = new Caller(klass) 
a call ("cat","Hi","there") 

Bu tür bir şey yapmak, derleme zamanı hatalarını çalışma zamanı hatalarına dönüştürür, ancak (aslında, sistem türünü siler), bu nedenle dikkatli kullanın.

(Düzenleme:. Ve yukarıdaki bağlantıda NameTransformer kullanımını bakınız - Eğer operatörlerini kullanmaya çalışırsanız yardımcı olacağını ekleme)

+0

'listesi (1, 2) çağrısı ("al" 1)' hatadır 'türü. bulunamadı: Int (1) gerekli: AnyRef Not: bir örtülü var scala.Int => java.lang.Integer, ancak Object'ten devralınan yöntemler belirsiz hale getirilir.Bu, bir örtülü örtüyü önlemek için hangi herhangi bir scala dönüştürebilirsiniz Herhangi bir AnyRef için.Aşağıdaki yazı tipini kullanmak isteyebilirsiniz: x: java.lang.Integer.' İlkel türleri ele almak için bir yol var mı? (Ben dinamik olarak argüman listesi oluşturmak istiyorum ... bir liste olabilir 'Any'' – dips

+1

@dips - Eğer' '' '' ile de çalışır .sIstanceOf [AnyRef] '', ya da hata önerileri gibi '1: java.lang.Integer' yapabilirsiniz. ve gerçekten ihtiyacınız varsa, burada olmanıza gerek kalmasa da, büyük/küçük harflerle dava açabilirsiniz. –

+0

Teşekkürler! Yani 'çağırma 'işlev imzamı şimdi alır' args: Any *' ve ben 'call' gövdesinde' Any'''''''''' '' '{{}} {{}}} {}. Umarım bu iyidir. Inceliklerini bilmiyorum, bu yüzden soruyor. – dips

6

Evet. Buna yansıma denir. Here's a link to one way, using some experimental stuff Ancak, Scala'nın dinamik bir dil olmadığını ve dil komutlarının yapabildiği bazı şeyleri kolaylıkla yapamayabileceğinizi unutmayın. Büyük ihtimalle dizede bir eşleşme yapıp daha sonra doğru yöntemi çağırmak daha iyidir.

class A { 
    def cat(s1: String, s2: String) = s1 + " " + s2 
} 
val a = new A 
val hi = "Hello" 
val all = "World" 
val method = a.getClass.getMethod("cat",hi.getClass,all.getClass) 
method.invoke(a,hi,all) 

Ve eğer isterseniz bunu sizin için yapar bir sınıf yapabilirsiniz Scala'da kolay artı dönüşüm için bir örtük olarak:

+0

Kırık bağlantı .... üzgünüm :(Ben aşağıda hatayı alıyorum –

0
scala> val commandExecutor = Map("cleanup" -> {()=> println("cleanup successfully")}) 
commandExecutor: scala.collection.immutable.Map[String,() => Unit] = Map(cleanup -> <function0>) 

scala> val command="cleanup" 
command: String = cleanup 

scala> commandExecutor(command).apply 
cleanup successfully 
Evet yapabilirsiniz
1

! Yöntem nesnesinin .invoke() yöntemine gereksiniminiz vardır. Aşağıdaki basit örnek:.

case class MyCaseClass(i: String) { 
    def sayHi = { 
    println(i) 
    } 
} 
val hiObj = MyCaseClass("hi") 
val mtdName = "sayHi" 
// Method itself as an object 
val mtd = hiObj.getClass.getMethod(mtdName) 
mtd.invoke(hiObj) 
İlgili konular