在Scala中声明一个null var

时间:2014-12-15 06:49:56

标签: scala null var

我已经读过null不应该在scala中使用。

如何在不使用myVar的情况下保持null未初始化?

class TestClass {

    private var myVar: MyClass = null

}

我知道我可以制作一个假的MyClass,它永远不会用来代替null。但这可以而且确实降低了代码的可理解性。

正如Rado所解释的那样,我可以更改null,如下所示。我知道我现在可以检查变量是否在运行期间设置,但是,如果我没有对该检查进行编程,那么在这种情况下使用Option没有任何好处。

来自Java,我觉得应该有一种方法可以简单地在编译时将var保留为未初始化,并在运行期间设置它而不使用Option类,因为正如我上面提到的,如果我没有' t代码为未设置的情况,然后为什么使用Option?

class TestClass {

    private var myVar: Option[MyClass] = None

    private def createVar() {
        myVar = Some(new MyClass)

        x: MyClass = myVar.get

    }
}

我在想我做的唯一其他方式是:

class TestClass {

    // Using dummy MyClass that will never be used.
    private var myVar: MyClass = new MyClass

    private def process(myVar: MyClass) {
        this.myVar = myVar

        myVar.useVarMethod()
    }
}

3 个答案:

答案 0 :(得分:6)

Scala方法是将变量声明为Option[MyClass]

class TestClass {
   private var myVar: Option[MyClass] = None

   private def createVar() {
     myVar = Some(new MyClass)
  }

  // Usage example:
  def useMyVar(): Unit = {
    myVar match {
      case Some(myClass) => {
        // Use myClass here ...
        println(myClass.toString)
      }
      case None => // What to do if myVar is undefined?
    }
  }
}

这样可以避免NullPointerException。您明确表示变量可能处于未定义状态。每次使用myVar时,都必须定义未定义时要执行的操作。 http://www.scala-lang.org/api/current/index.html#scala.Option

答案 1 :(得分:2)

  

我需要myVar类型为MyClass而不是Option [MyClass]。我明白了   可以使用Rado的更新答案,然后使用get方法,但是   还有其他办法吗?

使用Option时,您可以告诉编译器以及其他将读取/使用您的代码的人,可以不定义此值,代码将处理该条件而不会在运行时失败

另一种处理方法是每次访问变量之前都进行空值检查,因为它可能是null,因此会在运行时处抛出异常。

当您使用Option时,编译器会告诉您是否在编译时您没有处理可能未定义变量值的条件。

如果你考虑一下,这真的很重要。您已将运行时异常(确定性)转换为编译时错误。

答案 2 :(得分:0)

如果你想从像Option(支持map和flatMap)这样的东西中提取值,那么你就不一定要继续对Option是否包含一个值进行模式匹配(即是"有些")或不是(即#34;无")。

两种方法非常有用 - 如果你只想改变(或者#34; map")选项中的值,那么你可以使用map方法,它采用一般类型的函数: p>

f: A => B

所以在编译时你的情况最终会成为:

f: MyClass => B

当您映射选项时,如果该选项是"某些"然后将包含的值传递给映射函数,并应用该函数(如果您愿意,将MyClass更改为B),并将结果传回包装在Option中。如果您的选项是无,那么您只需返回无。

这是一个简单的例子:

scala> case class MyClass(value : String)
defined class MyClass

scala> val emptyOption : Option[MyClass] = None
emptyOption: Option[MyClass] = None

scala> val nonEmptyOption = Some(new MyClass("Some value"))
nonEmptyOption: Option[MyClass] = Some(MyClass(Some value)

尝试使用map:

从两个选项实例中提取值
scala> nonEmptyOption map { s => s.value + " mapped" }
res10: Option[String] = Some(Some value mapped)

scala> emptyOption map { s => s.value }
res11: Option[String] = None 

所以基本上,如果你映射一个空选项,你总是得到一个无。映射非空选项,您可以提取包含的值并对其进行转换,并将结果包装回选项中。请注意,您不需要明确检查任何模式...... map方法会处理它。

Flatmap有点难以解释,但它基本上没有大不相同,只是它需要一个具有类型的函数:

g: A => M[B]

它基本上允许你从Option中取出值(上面的类型签名中的' A'),对它做一些事情(即计算),然后返回结果(&#39) ; B') - 包裹在另一个容器中,例如另一个选项,列表......

相同的概念(无论如何,选项)如果Option是None,那么真正发生的事情仍然适用。 flatMap和map构成了Scala"的基础,用于理解"在很多其他地方,你可以阅读(并且做得比我更加正义!)。