【问题标题】:Scala Classes and ObjectsScala 类和对象
【发布时间】:2013-12-17 13:31:01
【问题描述】:

如果我在 Scala 中创建这样的类:

class Time(var hour: Int) {
  if (hour < 0) hour = 0
}

我可以轻松地创建一个新对象使用 x = new Time(4)

如果我需要为x 对象争取时间,我可以这样做 x.hour 我回来了 res5: Int = 4 这很酷。但考虑到我想更改xhour 变量,x.hour = 5 是否足够?我认同。有没有另一种方法可以做到这一点。

我的主要问题是。如果我不想使用 new 关键字,我将如何创建另一个对象?

【问题讨论】:

  • 请注意,您的代码不会阻止您设置负小时数:val x = new Time(0); x.hour = -3 仍会将 hour 设置为 -3

标签: scala


【解决方案1】:

正如其他人提到的,您可以使用案例类,但带有 var 构造函数参数的案例类通常是一个糟糕的选择,因为它意味着是不可变的。要模拟更改,您可以使用自动生成的 copy 方法(如果您有多个参数,它会变得更加有用)。

scala> case class Time(hour: Int) { require(hour > 0) }
defined class Time

scala> Time(-1)
java.lang.IllegalArgumentException: requirement failed
...

scala> val t1 = Time(1)
t1: Time = Time(1)

scala> val t2 = t1.copy(hour = 2)
t2: Time = Time(2)

更复杂的例子可以查看this question

【讨论】:

    【解决方案2】:

    如果您想省略 new 关键字,可以使用案例类:

    case class Time(var hour: Int) {
      if (hour < 0) hour = 0
    }
    
    val today = Time(-1)      //> today  : Time = Time(0)
    

    案例类也可用于case 语句的模式匹配。

    today match {
      case Time(0) => "foo"
      case Time(1) => "bar"
    }  //> res0: String = foo
    

    这是另一个关于案例类的 SO 帖子:Link

    【讨论】:

      【解决方案3】:

      如果不直接或间接使用new 关键字,您将无法创建另一个对象。案例类,似乎允许这样做:

      case class Person(name: String)
      val p1 = Person("John")
      

      但是,该案例类转换为如下内容:

      class Person(val name: String) {
        override def equals(other: AnyRef): Boolean = ???
        override def hashCode: Int = ???
        override def toString: String = s"Person($name)"
      }
      object Person {
        def apply(name: String) = new Person(name)
        def unapply(person: Person): Option[String] = ???
      }
      val p1 = Person.apply("John")
      

      所以那里有一个隐含的new

      【讨论】:

        【解决方案4】:

        第一个问题:是的。在终端中运行scala,您将获得 REPL,您可以在其中自己尝试类似的东西。

        scala> class Time(var hour: Int) {
             |   if (hour < 0) hour = 0
             | }
        defined class Time
        
        scala> val x = new Time(4)
        x: Time = Time@bcc8d5
        
        scala> x.hour = 5
        x.hour: Int = 5
        
        scala> x.hour
        res0: Int = 5
        

        第二个问题:有点不清楚你在问什么,但我认为是这样的:

        scala> :paste
        // Entering paste mode (ctrl-D to finish)
        
        class Time(var hour: Int) {
          if (hour < 0) hour = 0
        }
        object Time {
          def apply(hour: Int): Time = new Time(hour)
        }
        
        // Exiting paste mode, now interpreting.
        
        defined class Time
        defined module Time
        
        scala> val y = Time(7)
        y: Time = Time@7359fe
        
        scala> y.hour
        res1: Int = 7
        

        【讨论】:

          猜你喜欢
          • 2016-10-17
          • 1970-01-01
          • 2011-07-15
          • 2018-02-06
          • 1970-01-01
          • 2010-12-17
          • 1970-01-01
          • 2017-10-25
          • 1970-01-01
          相关资源
          最近更新 更多