Правильное использование опции в Scala?


Я несколько новичок в Scala и я не уверен, если я делаю вещи в Скала-эска способ.

В частности, я не уверен, если я использую опцию правильно, с вызовом .т. е., я в основном просто делаю в Java с нулевой чек. Кроме того, getMethodAndAnnotationFromInfaces способ, вероятно, может быть сделано лучше.

Прошу указать способы, которыми я мог бы более эффективно использовать возможности языка в ниже код:

for (val method <- clazz.getMethods) {
        val methodAndAnnotation = method.getAnnotation(annotationType) match {
            case annotation: MessageHandler => Some((method, annotation))
            case _ => getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
        }

        if (methodAndAnnotation.isDefined){
            // do something
        }
    }

getMethodAndAnnotationFromInterfaces функции:

def getMethodAndAnnotationFromInterfaces(interfaces: Array[java.lang.Class[_]], method: Method, annotationType: Class[_ <: java.lang.annotation.Annotation])
    : Option[(Method, java.lang.annotation.Annotation)] = {

    @tailrec
    def getMethodAndAnnotationFromInterfacesInner(interfaces: Array[java.lang.Class[_]], acc: Option[(Method, java.lang.annotation.Annotation)])
        : Option[(Method, java.lang.annotation.Annotation)] = {
        interfaces.length match {
            case 0 => acc
            case _ =>
                try {
                    interfaces.head.getMethod(method.getName, method.getParameterTypes: _*) match {
                        case newMethod: Method =>
                            val newAnnotation = newMethod.getAnnotation(annotationType)
                            if (newAnnotation != null && acc.isDefined) {
                                throw new RuntimeException("The annotation is applied to the method in more than one interface of the class.")
                            }
                            getMethodAndAnnotationFromInterfacesInner(interfaces.tail, Some((newMethod, newAnnotation)))
                        case _ => getMethodAndAnnotationFromInterfacesInner(interfaces.tail, acc)
                    }
                } catch {
                    case e: NoSuchMethodException => getMethodAndAnnotationFromInterfacesInner(interfaces.tail, acc)
                }
        }
    }

    getMethodAndAnnotationFromInterfacesInner(interfaces, None)
}


509
2
задан 16 октября 2011 в 11:10 Источник Поделиться
Комментарии
3 ответа

Вы можете написать это так:

for (val method <- clazz.getMethods) {
val methodAndAnnotation = method.getAnnotation(annotationType) match {
case annotation: MessageHandler => Some((method, annotation))
case _ => getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
}

methodAndAnnotation match {
case Some((method, annotation)) => // do something
case None => //whatever is relevant
}
}

Или короче:

for (val method <- clazz.getMethods) {
method.getAnnotation(annotationType) match {
case annotation: MessageHandler => // do something with method and annotation
case _ => {
val v = getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
//whatever is relevant
}
}
}

Но это зависит от того, что вы хотите сделать / если у вас что-то делать, когда getMethodAndAnnotationFromInterfaces возвращает никто.

1
ответ дан 17 октября 2011 в 06:10 Источник Поделиться

Для "scalaesque способ" разобраться с вариантом, исследование Тони Морриса вариант шпаргалку. Кроме того, вы можете использовать для выделения, а также (если вы не хотите сделать ничего в случае нет):

for (value <- optionValue) {...}

1
ответ дан 17 октября 2011 в 01:10 Источник Поделиться

Еще один улучшения использовать отражение, Скала который приходит в 2.10:

import scala.reflect.runtime.Mirror
val c = Mirror.classToType(classOf[X])
val members = c.parents map { _.members filter (_.isMethod) }
val ann = Mirror.classToSymbol(classOf[Ann])
val meths = members map { _ filter (_ hasAnnotation ann) }

Выход не идеальный, но код короче, понятно, Скала и печатает ожидаемый результат:

meths: List[List[scala.reflect.runtime.Mirror.Symbol]] = List(List(), List(method c, method a), List())

Я проверил это с помощью следующего кода:

// Java
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Ann {}

// Scala
trait T {
@Ann
def a: Int
def b(i: Int): String
@Ann
def c(s: String): String
}
class X extends T {
def a: Int = 5
def b(i: Int) = i.toString
def c(s: String) = "("+s+")"
}

0
ответ дан 17 октября 2011 в 04:10 Источник Поделиться