我已经读过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()
}
}
答案 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"的基础,用于理解"在很多其他地方,你可以阅读(并且做得比我更加正义!)。