Scala:作为方法参数的动态选择条件
我的意图是在Scala中创建一个函数,它接受某种动态查询(类似于模式匹配中的Scala:作为方法参数的动态选择条件,scala,pattern-matching,anonymous-types,Scala,Pattern Matching,Anonymous Types,我的意图是在Scala中创建一个函数,它接受某种动态查询(类似于模式匹配中的case表达式),并在列表中返回匹配实例。假设列表由案例类Person的实例组成,这些实例几乎没有不同类型的属性。函数应该能够接受某些字段的值的动态组合,并返回匹配的Persons。我特别寻找一个干净的解决方案。使用此函数的一种可能方法是传递匿名类型的对象作为查询(“模式”): def find(?):List={?} val matches=find(新的{val name=“name”;val gender=gend
case
表达式),并在列表中返回匹配实例。假设列表由案例类Person
的实例组成,这些实例几乎没有不同类型的属性。函数应该能够接受某些字段的值的动态组合,并返回匹配的Person
s。我特别寻找一个干净的解决方案。使用此函数的一种可能方法是传递匿名类型的对象作为查询(“模式”):
def find(?):List={?}
val matches=find(新的{val name=“name”;val gender=gender.MALE})
理想情况下,我想开发一种干净的传递条件的方式,而不是具体的价值观,但这不是必要的。因为我正在学习Scala,所以我不知道实现这种东西的所有技术。在C#中,我使用了匿名类型(类似于上面的第二行代码)和动态
参数来实现类似的功能。什么是Scala中干净优雅的解决方案?我不确定这是否是您想要的,但让我们这样试试:
首先,我们将Person
定义为case类Person(name:String,gender:gender.Value)
其中gender
是已经定义的枚举
然后,我们创建一个查询
案例类,该类具有相同的字段,但作为默认为无
的选项,以及一个将查询与人进行比较的方法:
case class Query(name: Option[String] = None,
gender: Option[Gender.Value] = None){
def ===(person: Person) = check(person.name, name) &&
check(person.gender, gender)
private def check[T](field: T, q: Option[T]) = field == q.getOrElse(field)
}
不幸的是,在这个解决方案中,==
必须为每个字段分别调用check
。现在就这样吧。也许这就足够了(例如,因为字段列表不会更改)
请注意,check
如果查询的选项为None
,则返回true
,因此您不必通过查询的所有字段:
val q = Query(name = Some("Ann")) // the gender is not important
q === Person("Ann", Gender.FEMALE) // returns true
最后是find
方法:
def find(people: List[Person], query: Query) = people.filter(query === _)
匿名谓词不够清晰解决方案xs.find(person=>person.name==“name”&&person.gender==gender.MALE)
?如果条件是静态的,它们是。例如,在运行之前,不确定是否应检查名称。您所描述的内容类似于ScalaTest的matchers,您可以编写类似于person-should have('name(“name”),'gender(gender.MALE))
。当匹配器用于断言时,您可能能够根据自己的目的调整实现。查看“使用Have检查任意属性”:
def find(people: List[Person], query: Query) = people.filter(query === _)