在Scala中声明空变量
我已经读到在Scala中声明空变量,scala,null,var,Scala,Null,Var,我已经读到null不应该在scala中使用 如果不使用null,我如何使myVar保持未初始化状态 class TestClass { private var myVar: MyClass = null } 我知道我可以制作一个虚拟的MyClass,它永远不会代替null。但这会降低代码的可理解性 正如Rado所解释的,我可以更改null,如下所示。我知道我现在可以检查变量是否在运行时设置,但是,如果我没有对该检查进行编程,那么在这种情况下使用该选项没有任何好处 来自Java,我觉
null
不应该在scala中使用
如果不使用null
,我如何使myVar
保持未初始化状态
class TestClass {
private var myVar: MyClass = null
}
我知道我可以制作一个虚拟的MyClass
,它永远不会代替null
。但这会降低代码的可理解性
正如Rado所解释的,我可以更改null
,如下所示。我知道我现在可以检查变量是否在运行时设置,但是,如果我没有对该检查进行编程,那么在这种情况下使用该选项没有任何好处
来自Java,我觉得应该有一种方法,在编译时不初始化var,在运行时设置它,而不使用Option类,因为正如我前面提到的,如果我不为unset情况编码,那么为什么要使用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()
}
}
Scala方法是将变量声明为
选项[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
时,都必须定义如果未定义该变量,该怎么办。
Scala方法是将变量声明为
选项[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
时,都必须定义如果未定义该变量,该怎么办。
我需要myVar的类型为MyClass而不是Option[MyClass]。我知道我
可以使用Rado的更新答案,然后使用get方法,但是
还有别的办法吗
当您使用选项时
可以告诉编译器和将阅读/使用您的代码的所有其他人,不定义此值是可以的,代码将处理该情况,并且不会在运行时失败
另一种处理方法是在每次访问变量之前进行空检查,因为它可能是null
,因此在运行时引发异常
当您使用选项时
,编译器将告诉您是否在编译时未处理变量值可能未定义的情况
如果你仔细想想,这真是一件大事。您已将运行时异常(确定性)转换为编译时错误
我需要myVar的类型为MyClass而不是Option[MyClass]。我知道我
可以使用Rado的更新答案,然后使用get方法,但是
还有别的办法吗
当您使用选项时
可以告诉编译器和将阅读/使用您的代码的所有其他人,不定义此值是可以的,代码将处理该情况,并且不会在运行时失败
另一种处理方法是在每次访问变量之前进行空检查,因为它可能是null
,因此在运行时引发异常
当您使用选项时
,编译器将告诉您是否在编译时未处理变量值可能未定义的情况
如果你仔细想想,这真是一件大事。您已将运行时异常(确定性)转换为编译时错误 如果您想从某个选项(支持map和flatMap)中提取值,那么您不必继续对该选项是否包含值(即,是“Some”)进行模式匹配(即,是“None”) 有两种方法非常有用-如果您只想更改(或“映射”)选项中的值,则可以使用map方法,该方法使用的函数的一般类型为:
f: A => B
因此,在您的情况下,编译时的结果是:
f: MyClass => B
当映射一个选项时,如果该选项是“Some”,则包含的值将传递给映射函数,并应用该函数(如果愿意,将MyClass更改为B…),然后将结果包装在一个选项中传递回。如果你的选择是“无”,那么你只会得到一个“无”
下面是一个简单的例子:
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)
尝试使用映射从两个选项实例中提取值:
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]
这基本上允许您从选项(上面类型签名中的“A”)中取出值,对其执行一些操作(即计算),然后返回结果(“B”)——包装在另一个容器中,例如另一个选项,列表
同样的概念(无论如何,在整个选项中)也适用,即如果该选项为“无”,那么实际上什么也不会发生。flatMap和map构成了Scala“理解”的基础,你可以在很多其他地方阅读到它(而且比我做得更公正!!) 如果您想从某个选项(支持map和flatMap)中提取值,那么您不必继续对该选项是否包含值(即,是“Some”)进行模式匹配(即,是“None”) 有两种方法非常有用-如果您只想更改(或“映射”)选项中的值,则可以使用map方法,该方法使用的函数的一般类型为:
f: A => B
因此,在您的情况下,编译时的结果是:
f: MyClass => B
映射选项时,如果该选项是“Some”,则将包含的值传递给映射函数,并应用该函数(如果愿意,将MyClass更改为AB…),然后将结果传递给ba