2016-11-13 81 views
2

我想迭代使用反射的给定类的构造函数。 问题是我需要对每个元素执行一些操作,然后只返回匹配谓词的那些元素。下面的代码抛出异常斯卡拉flatMap over getConstructors方法(反射)

classOf[String].getConstructors.flatMap(x=> doSomething(x); if(predicate(x)) Some(x) else None) 

例外:

argument expression's type is not compatible with formal parameter type; 
found : java.lang.reflect.Constructor[_] => Iterable[java.lang.reflect.Constructor[?0(in value $anonfun)]] forSome { type ?0(in value $anonfun) } 
required: java.lang.reflect.Constructor[_] => scala.collection.GenTraversableOnce[?B] 

我不知道这是可以做到的理解,因为我需要调用做一些事情每个元素(不只是为持有谓词的):

for{ 
    x <- c.getConsturctors 
    //doSomething(x) ?? 
    if predicate(x) 
}yield{ 
    //doSomething(x) - only for the ones that holds the predicate 
    x 
} 

调用c.getMethods的作品,所以我猜它是与返回类型(数组[方法] VS阵[构造[_]])... ?

flatMap - 阿列克谢·罗曼诺夫回答

的理解(有pamu的帮助下):

for{ 
    x <- c.getConsturctors 
    _ = doSomething(x) 
    if predicate(x) 
}yield x 
+0

需要更多关于'doSomething'和'predicate'的信息来告诉确切的错误 – pamu

+0

它并不重要,可以说doSomething打印x和谓词只是返回true –

回答

1

由于类型推断的实现细节,斯卡拉结束了,你想Iterable[java.lang.reflect.Constructor[A] forSome { type A }](或者更短,Iterable[java.lang.reflect.Constructor[_]]Iterable[java.lang.reflect.Constructor[A]] forSome { type A }。注释类型应该工作:

c.getConstructors.flatMap { x => 
    doSomething(x) 
    (if (predicate(x)) Some(x) else None): Option[Constructor[_]] 
} 

,但我必须承认,我不明白为什么出现问题。

+0

雅我猜它与implicits有关..仍然有趣,知道如果有人知道为什么.. –

1

使用collect而不是flatMap,然后再返回SomeNone

classOf[String].getConstructors.toList 
    .collect { case elem if predicate(elem) => doSomething(elem) } 

使用flatMap

classOf[String].getConstructors.toList.flatMap { elem => 
    doSomething(elem); 
    if (predicate(elem)) { 
    List(elem) 
    } else List() 
} 

使用换理解

for { 
elem <- classOf[String].getConstructors.toList 
_ = doSomething(elem) 
val result = if (predicate(elem) List(elem) else List() 
} yield result 
+0

它的工作原理(但if应该在case子句中所以不管谓词结果如何,每次迭代都会调用一些东西)。无论如何,我正在寻找一种方法来解决问题,使用flatMap或理解。 –

+0

关于flatmap-我不想列表,但选项。 for是有用的,但我会将其改为:... if(predicate(elem))} yield elem –

+0

“我不想列表但选项”选项将由隐式转换为列表,以满足预期类型。 –