首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala性质问题

Scala性质问题
EN

Stack Overflow用户
提问于 2010-11-11 20:20:57
回答 3查看 2.7K关注 0票数 11

我仍然在学习Scala,但我认为有趣的是Scala模糊了方法和字段之间的界限。例如,我可以建一个这样的类.

代码语言:javascript
复制
class MutableNumber(var value: Int)

这里的关键是构造函数参数中的var允许我像java中的getter/setter一样使用'value‘字段。

代码语言:javascript
复制
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)

如果我想添加约束,可以切换到使用方法来代替实例字段:

代码语言:javascript
复制
// require all mutable numbers to be >= 0
class MutableNumber(private var _value: Int) {
    require(_value >= 0)

    def value: Int = _value
    def value_=(other: Int) {
        require(other >=0)
        _value = other
    }
}

客户端代码不会中断,因为API不会更改:

代码语言:javascript
复制
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)

我挂起的是添加到Scala-2.8中的命名参数特性。如果我使用命名参数,我的api确实会改变,它确实破坏了API。

代码语言:javascript
复制
val num = new MutableNumber(value=5)  // old API
val num = new MutableNumber(_value=5) // new API

num.value = 6
println(num.value)

有什么优雅的解决办法吗?我应该如何设计我的MutableNumber类,以便以后在不破坏API的情况下添加约束?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-11-11 20:38:14

您可以使用与case类相同的技巧:使用伴生对象。

代码语言:javascript
复制
object Example {
  class MutableNumber private (private var _value: Int) {
    require (_value >= 0)
    def value: Int = _value
    def value_=(i: Int) { require (i>=0); _value = i }
    override def toString = "mutable " + _value
  }
  object MutableNumber {
    def apply(value: Int = 0) = new MutableNumber(value)
  }
}

在这里,它正在工作(并证明,正如所构造的那样,您必须将对象用于创建,因为构造函数被标记为私有):

代码语言:javascript
复制
scala> new Example.MutableNumber(5)
<console>:10: error: constructor MutableNumber cannot be accessed in object $iw
   new Example.MutableNumber(5)
   ^

scala> Example.MutableNumber(value = 2)
res0: Example.MutableNumber = mutable 2

scala> Example.MutableNumber()
res1: Example.MutableNumber = mutable 0
票数 11
EN

Stack Overflow用户

发布于 2010-11-11 22:50:39

谢谢你的回答!顺便说一句,我认为Scala人可能意识到有一个问题:

Scala2.8中的新特性:命名和默认参数

..。到目前为止,参数的名称对于库开发人员来说是一个有点武断的选择,并不被认为是API的重要组成部分。这种情况突然改变了,因此如果参数sep在以后的版本中重命名为分隔符,则对mkString的方法调用(sep=“")将无法编译。

Scala2.9为这个问题实现了一个简洁的解决方案,但是在我们等待它的时候,如果它们的名称将来可能发生变化,那么请小心地按名字引用参数。

  • http://www.artima.com/scalazine/articles/named_and_default_parameters_in_scala.html
票数 2
EN

Stack Overflow用户

发布于 2010-11-12 23:01:04

代码语言:javascript
复制
class MutableNumber {
    private var _value = 0 //needs to be initialized
    def value: Int = _value
    def value_=(other: Int) {
        require(other >=0) //this requirement was two times there
        _value = other
    }
}

可以修改大括号内任何类的所有成员。

代码语言:javascript
复制
val n = new MutableNumber{value = 17}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4158894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档