Scala flatMap over getConstructors 方法(反射)
Scala flatMap over getConstructors method (reflection)
我正在尝试使用反射迭代给定 class 的构造函数。
问题是我需要对每个元素做一些事情,然后只 return 匹配某些谓词的那些。以下代码抛出异常
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]
我不确定这是否可以通过理解来完成,因为我需要在每个元素上调用 do something(不仅仅是那些包含谓词的元素):
for{
x <- c.getConsturctors
//doSomething(x) ??
if predicate(x)
}yield{
//doSomething(x) - only for the ones that holds the predicate
x
}
调用 c.getMethods 有效,所以我猜它与 return 类型有关(Array[Methods] vs Array[Constructor[_]])...?
回答:
flatMap - Alexey Romanov 的回答
理解(在 pamu 的帮助下):
for{
x <- c.getConsturctors
_ = doSomething(x)
if predicate(x)
}yield x
使用collect
代替flatMap
然后返回Some
,None
classOf[String].getConstructors.toList
.collect { case elem if predicate(elem) => doSomething(elem) }
使用平面地图
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
由于类型推断实现的细节,Scala 在您想要 Iterable[java.lang.reflect.Constructor[A] forSome { type A }]
的地方以 Iterable[java.lang.reflect.Constructor[A]] forSome { type A }
结束(或更短,Iterable[java.lang.reflect.Constructor[_]]
)。注释类型应该有效:
c.getConstructors.flatMap { x =>
doSomething(x)
(if (predicate(x)) Some(x) else None): Option[Constructor[_]]
}
但我必须承认我不明白为什么会出现问题。
我正在尝试使用反射迭代给定 class 的构造函数。 问题是我需要对每个元素做一些事情,然后只 return 匹配某些谓词的那些。以下代码抛出异常
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]
我不确定这是否可以通过理解来完成,因为我需要在每个元素上调用 do something(不仅仅是那些包含谓词的元素):
for{
x <- c.getConsturctors
//doSomething(x) ??
if predicate(x)
}yield{
//doSomething(x) - only for the ones that holds the predicate
x
}
调用 c.getMethods 有效,所以我猜它与 return 类型有关(Array[Methods] vs Array[Constructor[_]])...?
回答:
flatMap - Alexey Romanov 的回答
理解(在 pamu 的帮助下):
for{
x <- c.getConsturctors
_ = doSomething(x)
if predicate(x)
}yield x
使用collect
代替flatMap
然后返回Some
,None
classOf[String].getConstructors.toList
.collect { case elem if predicate(elem) => doSomething(elem) }
使用平面地图
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
由于类型推断实现的细节,Scala 在您想要 Iterable[java.lang.reflect.Constructor[A] forSome { type A }]
的地方以 Iterable[java.lang.reflect.Constructor[A]] forSome { type A }
结束(或更短,Iterable[java.lang.reflect.Constructor[_]]
)。注释类型应该有效:
c.getConstructors.flatMap { x =>
doSomething(x)
(if (predicate(x)) Some(x) else None): Option[Constructor[_]]
}
但我必须承认我不明白为什么会出现问题。