2010-01-13 8 views

답변

25

당신은 자바에서 반사하여이 작업을 수행 할 수

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

이런 종류의 작업을 수행하는 것은 컴파일 타임 오류를 런타임 오류로 변환합니다 (즉, 본질적으로 유형 시스템을 우회합니다). 따라서주의해서 사용하십시오.

(편집 :. 위의 링크에서 NameTransformer의 사용을 참조 - 당신이 연산자를 사용하려고하면 도움이됩니다 추가)

+0

'목록 (1, 2) 호출 ("받아"1) '오류가'유형입니다. 불일치, 발견 : Int (1) 필수 : ​​AnyRef 참고 : scala.Int => java.lang.Integer에서 암시 적으로 존재하지만 Object에서 상속 된 메서드는 모호하게 렌더링됩니다. 이것은 이 모든 스칼라 . Any Any에 해당합니다. 형식 ascription을 사용할 수 있습니다. x : java.lang.Integer.' 기본 유형을 처리 할 수 ​​있습니까? (동적으로 인수 목록을 생성하고 싶습니다. 'Any') – dips

+1

@dips - 당신은'.asInstanceOf [AnyRef]'를 사용하고 ('Any'도 함께 사용 가능), 오류가 암시하는''1 : java.lang.Integer' 또는 원시와 일치시킬 수 있습니다 필요한 경우 사례별로 처리해야합니다. 여기에있을 필요는 없습니다. –

+0

감사! 그래서 우리의'call' 함수 시그니처는'args : Any *'를 취하고 그것을'args map {_.asInstanceOf [AnyRef]}'처럼'call'의 본문에서'AnyRef *'로 변환합니다. 희망이 괜찮아요. 미묘함을 모른 채 묻는다. – dips

6

예. 반사라고합니다. Here's a link to one way, using some experimental stuff 그러나 스칼라는 동적 언어가 아니므로 스크립팅 언어로 수행 할 수있는 일을 쉽게 수행하지 못할 수도 있습니다. 문자열에 대한 일치를 수행 한 다음 올바른 메서드를 호출하는 것이 좋습니다.

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) 

을 그리고 당신이 원하는 경우에 당신은 당신을 위해이 작업을 수행하는 클래스를 만들 수 있습니다 스칼라에서 쉽게 플러스 전환에 대한 암시로 :

+0

깨진 링크 .... 죄송합니다 :(내가 다음에 오류가 발생하고 –

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 
예 당신이 할 수있는
1

! .invoke() 메서드 개체의 메서드가 필요합니다. 아래의 간단한 예 :.

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) 
관련 문제