Scala 在不重复参数列表的情况下预处理案例类构造函数的参数
我有一个案例类,有很多参数:Scala 在不重复参数列表的情况下预处理案例类构造函数的参数,scala,Scala,我有一个案例类,有很多参数: case class Document(id:String, title:String, ...12 more params.. , keywords: Seq[String]) 对于某些参数,我需要在创建对象之前进行一些字符串清理(修剪等) 我知道我可以添加一个带有apply函数的伴生对象,但我最不想做的就是在代码中编写两次参数列表(case类构造函数和伴生对象的apply) Scala在这方面有什么帮助吗?我的一般建议是: 您的目标(数据预处理)是伴生对象
case class Document(id:String, title:String, ...12 more params.. , keywords: Seq[String])
对于某些参数,我需要在创建对象之前进行一些字符串清理(修剪等)
我知道我可以添加一个带有apply函数的伴生对象,但我最不想做的就是在代码中编写两次参数列表(case类构造函数和伴生对象的apply)
Scala在这方面有什么帮助吗?我的一般建议是:
- 您的目标(数据预处理)是伴生对象的完美用例——因此,尽管有样板,它可能是最惯用的解决方案
- 如果case类参数的数量很大,那么builder模式肯定会有所帮助,因为您不必记住参数的顺序,并且您的IDE可以帮助您调用builder成员函数。为case类构造函数使用命名参数也允许使用随机参数顺序,但据我所知,命名参数没有IDE自动完成=>使构建器类稍微方便一些。然而,使用构建器类会引发如何处理强制指定某些参数的问题——简单的解决方案可能会导致运行时错误;这篇文章有点冗长。在这方面,带有默认参数的case类更优雅
preprocessed
,默认参数为false
。每当您想要使用实例val d:Document
,您都可以调用通过case类copy方法实现的d.preprocess()
(以避免再次键入所有参数):
但是:您不能阻止客户端初始化预处理
设置为true
另一个选项是将一些参数设置为private val
,并为预处理的数据公开相应的getter:
case class Document(id: String, title: String, private val _keywords: Seq[String]) {
val keywords = _keywords.map(kw => kw.trim)
}
但是:模式匹配和默认的
toString
实现并不能完全满足您的需求…在更改上下文半小时后,我以全新的眼光看待这个问题,并提出了以下建议:
case class Document(id: String, title: String, var keywords: Seq[String]) {
keywords = keywords.map(kw => kw.trim)
}
我只需在类主体中添加var
和清理数据,即可使参数可变
好吧,我知道,我的数据不再是一成不变的,马丁·奥德斯基可能会在看到这一点后杀死一只小猫,但是嘿。。我成功地完成了我想添加的3个字符。我称之为胜利:)不太可能,因为这有点违背了案例类的概念。一个普通的类构造函数或重写
apply
将不得不这样做。使用有趣的方法:保持文档不变,但在构造函数的污染方面有所欠缺。private val\u关键字
解决方案很难看,但效果非常好。toString在我的测试中表现良好。你有什么问题?另外:我的自动JSON序列化程序很高兴地忽略了“_关键字”,所以我已经准备好了。谢谢@sscarduzio:toString
实现使用(未处理的)\u关键字
成员,而不是预处理的关键字
。这就是行为显然是可以的(case类对关键字getter一无所知),但它可能会造成混淆。我没想到您会那么容易地放弃不变性:)。仍然有希望使其成为val--请参阅我更新的答案。。。
case class Document(id: String, title: String, var keywords: Seq[String]) {
keywords = keywords.map(kw => kw.trim)
}