加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala构造函数,命名参数和隐式Getters / Setter

发布时间:2020-12-16 19:01:06 所属栏目:安全 来源:网络整理
导读:是否可以在 Scala构造函数中使用命名参数,稍后在覆盖getter和setter上,而不会破坏构造函数接口或使代码非常丑陋? 拿下以下的scala代码 class Person( var FirstName: String,var LastName: String ) 漂亮干净这将创建一个简单的类,称为人,我们可以使用以下
是否可以在 Scala构造函数中使用命名参数,稍后在覆盖getter和setter上,而不会破坏构造函数接口或使代码非常丑陋?

拿下以下的scala代码

class Person( var FirstName: String,var LastName: String )

漂亮干净这将创建一个简单的类,称为人,我们可以使用以下方式

val john = new Person( FirstName="John",LastName="Doe" )
john.FirstName = "Joe"
println( john.FirstName )

之后,我们决定要对FirstName设置器添加一些验证.因此,我们创建一个新的私有局部变量并覆盖getter和setter方法

class Person( var _FirstName: String,var _LastName: String ) {

    def FirstName = _FirstName  
    def FirstName_= (value:String) = _FirstName = value

}

仍然有点干净,但为了做到这一点,我们不得不改变构造函数的参数名称,从而打破外部接口.

我想出的这个问题的第一个解决方案是

class Person {
    var _FirstName:String = null 
    var LastName:String  = null

    def FirstName = _FirstName  
    def FirstName_= (value:String) = _FirstName = value

    def this( FirstName: String,LastName: String ){
        this()
        this._FirstName = FirstName
        this.LastName = LastName 
    }

}

这是一些丑陋和不实际的,并删除了大部分的好原因我使用scala在第一位.

有没有更好的方法呢?

tl; dr如何覆盖在默认构造函数中定义的成员的getter / setter,而不会使代码丑化或更改公共接口?

解决方法

如果您尚未使用隐式转换来创建参数,则可以执行以下操作:

def validateName(s: String) = {
  if (s.length>0 && s(0).isUpper) s
  else throw new IllegalArgumentException(s+" is not a name!")
}

object Example {
  private[Example] class ValidatedName(val s: String) { }
  class Person(var firstName: ValidatedName,var lastName: String) { }
  implicit def string2valid(s: String) = new ValidatedName(validateName(s))
  implicit def valid2string(v: ValidatedName) = v.s
}

scala> new Example.Person("Joe","Schmoe")
res17: Example.Person = Example$Person@51887dd5

scala> new Example.Person("ee","cummings")
java.lang.IllegalArgumentException: ee is not a name!

它不是二进制兼容的,但它是源兼容的(再次,如果名称还没有依赖于隐式转换).

另一个稍长一点的可能性是创造一个潜行祖先:

class CheckedPerson(private var first: String,var lastName: String) {
  def firstName = first
  def firstName_=(s: String) { first = validateName(s) }
}
class Person(firstName: String,lastName: String) extends
  CheckedPerson(validateName(firstName),lastName) { }

我不知道二进制兼容性,但肯定会提供源兼容性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读