2016-11-13 79 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

「我不想列表但選項」選項將由隱式轉換爲列表,以滿足預期類型。 –