메서드의 이름, 해당 메서드 및 일부 인수를 지원하는 개체를 포함하는 문자열이 있다고 가정하면 동적으로 호출 할 수있는 언어 기능이 있습니까?이름이 문자열에 저장된 메서드를 호출 할 수있는 스칼라 기능이 있습니까?
루비의 send
과 같은 종류입니다.
메서드의 이름, 해당 메서드 및 일부 인수를 지원하는 개체를 포함하는 문자열이 있다고 가정하면 동적으로 호출 할 수있는 언어 기능이 있습니까?이름이 문자열에 저장된 메서드를 호출 할 수있는 스칼라 기능이 있습니까?
루비의 send
과 같은 종류입니다.
당신은 자바에서 반사하여이 작업을 수행 할 수
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의 사용을 참조 - 당신이 연산자를 사용하려고하면 도움이됩니다 추가)
예. 반사라고합니다. 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)
을 그리고 당신이 원하는 경우에 당신은 당신을 위해이 작업을 수행하는 클래스를 만들 수 있습니다 스칼라에서 쉽게 플러스 전환에 대한 암시로 :
깨진 링크 .... 죄송합니다 :(내가 다음에 오류가 발생하고 –
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
예 당신이 할 수있는
! .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)
'목록 (1, 2) 호출 ("받아"1) '오류가'유형입니다. 불일치, 발견 : Int (1) 필수 : AnyRef 참고 : scala.Int => java.lang.Integer에서 암시 적으로 존재하지만 Object에서 상속 된 메서드는 모호하게 렌더링됩니다. 이것은 이 모든 스칼라 . Any Any에 해당합니다. 형식 ascription을 사용할 수 있습니다. x : java.lang.Integer.' 기본 유형을 처리 할 수 있습니까? (동적으로 인수 목록을 생성하고 싶습니다. 'Any') – dips
@dips - 당신은'.asInstanceOf [AnyRef]'를 사용하고 ('Any'도 함께 사용 가능), 오류가 암시하는''1 : java.lang.Integer' 또는 원시와 일치시킬 수 있습니다 필요한 경우 사례별로 처리해야합니다. 여기에있을 필요는 없습니다. –
감사! 그래서 우리의'call' 함수 시그니처는'args : Any *'를 취하고 그것을'args map {_.asInstanceOf [AnyRef]}'처럼'call'의 본문에서'AnyRef *'로 변환합니다. 희망이 괜찮아요. 미묘함을 모른 채 묻는다. – dips