在 Scala 2.10 中验证和扩展构造函数参数的最佳方法 [英] Best way to validate and extend constructor parameters in Scala 2.10

查看:49
本文介绍了在 Scala 2.10 中验证和扩展构造函数参数的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个包含多个字段的类,例如字符串、布尔值等,并且在构建该类时,我希望有一个与每个字段关联的字段名并验证该字段(对字符串使用正则表达式).理想情况下,我只想在构造函数中指定参数需要满足某些条件.

I want to have a class that has a number of fields such as String, Boolean, etc and when the class is constructed I want to have a fieldname associated with each field and verify the field (using regex for strings). Ideally I would just like specify in the constructor that the parameter needs to meet certain criteria.

一些示例代码如何:

case class Data(val name: String ..., val fileName: String ...) {
  name.verify
  // Access fieldName associated with the name parameter.
  println(name.fieldName) // "Name"
  println(fileName.fieldName) // "File Name"
}

val x = Data("testName", "testFile")
// Treat name as if it was just a string field in Data
x.name // Is of type string, does not expose fieldName, etc

有没有一种优雅的方法来实现这一目标?

Is there an elegant way to achieve this?

我不认为我已经能够清楚地了解我所追求的.我有一个带有许多字符串参数的类.这些参数中的每一个都需要以特定方式进行验证,我还希望有一个与每个参数关联的字符串 fieldName.但是,我仍然希望能够将参数视为普通字符串(参见示例).

I don't think I have been able to get across clearly what I am after. I have a class with a number of string parameters. Each of those parameters needs to validated in a specific way and I also want to have a string fieldName associated with each parameter. However, I want to still be able to treat the parameter as if it was just a normal string (see the example).

我可以将逻辑编码到 Data 中,并作为每个参数的 Data 伴随对象的应用方法,但我希望有更通用的东西.

I could code the logic into Data and as an apply method of the Data companion object for each parameter, but I was hoping to have something more generic.

推荐答案

在构造函数中放置逻辑(例如参数验证)是可疑的.从构造函数抛出异常是双重的.

Putting logic (such as parameter validation) in constructors is dubious. Throwing exceptions from constructors is doubly so.

通常这种创建模式最好与一个或多个工厂方法或某种构建器一起使用.

Usually this kind of creational pattern is best served with one or more factory methods or a builder of some sort.

对于基本工厂,只需定义一个带有您想要的工厂方法的伴侣.如果您想要相同的简写构造符​​号(new-free),您可以重载预定义的 apply(尽管您不能替换签名与 case class 完全是构造函数).

For a basic factory, just define a companion with the factory methods you want. If you want the same short-hand construction notation (new-free) you can overload the predefined apply (though you may not replace the one whose signature matches the case class constructor exactly).

如果你想让你的客户端代码免于在验证失败时处理异常的麻烦,你可以返回 Option[Data]Either[ErrorIndication, Data] 代替.或者你可以使用 ScalaZ 的 Validation,我将任意声明它超出了这个答案的范围(因为我对它不够熟悉......)

If you want to spare your client code the messiness of dealing with exceptions when validation fails, you can return Option[Data] or Either[ErrorIndication, Data] instead. Or you can go with ScalaZ's Validation, which I'm going to arbitrarily declare to be beyond the scope of this answer ('cause I'm not sufficiently familiar with it...)

但是,您不能拥有在它们呈现的属性方面不同的实例.甚至子类都不能从公共 API 中减去.如果您需要能够做到这一点,您将需要一个更复杂的构造,例如用于公共部分的 trait 和用于变体的单独 case classes 和/或扩展.

However, you cannot have instances that differ in what properties they present. Not even subclasses can subtract from the public API. If you need to be able to do that, you'll need a more elaborate construct such as a trait for the common parts and separate case classes for the variants and / or extensions.

这篇关于在 Scala 2.10 中验证和扩展构造函数参数的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆