如何使用Option [T]在scala中很好地处理空值?

时间:2016-05-11 03:11:12

标签: scala

Java代码:

public static Connection connection = null;
public static void main(String[] args) {
    if(connection == null){
        connection = ConnectionFactory.createConnection(conf);
    }
    //using connection object to do something
}

转换为Scala代码:

有人告诉我使用Option[T]来处理null值,但我不知道如何使用Option[T],我认为这非常麻烦。

Scala代码:

    var connOpt: Option[Connection] = None
    def main(args: Array[String]) {
        //check `connOpt` Option
        connOpt match {
            case Some(connection) => { /* using `connection` to do something-----code1  */    }
            case _ => {
                val connection = ConnectionFactory.createConnection()
                connOpt = Option(connection)
                // using `connection` to do something------code2
                }   
        }
    }

你可以看到scala代码。

  1. 我需要使用connOpt时检查connOpt

  2. code1 code2 是相同的代码,我需要写两次,我知道我可以使用函数来封装code1或code2,但这很麻烦

  3. 如何处理这种情况?

4 个答案:

答案 0 :(得分:3)

我认为你可以使用'fold'方法做你想做的事情

var connOpt:Option[Connection] = None
def main(args: Array[String]) {
    val connection = connOpt.fold(ConnectionFactory.createConnection()){conn => conn}
    //using connection object to do something
}

上面提到的代码逻辑与你没有两次写'code1'和'code2'的java代码相同。

使用以下示例解释'fold'的用法

obj.fold{/*the obj is null, you can return the value you want*/}{a => a
/*if the obj is Some(value), the 'a' is just the 'value'*/
}

祝你好运

答案 1 :(得分:2)

这取决于您的业务逻辑;与编程语言无关。

如果连接尝试失败,让组件保持活动是否有意义?

您可能希望提早失败":如果您无法连接,请抛出异常或停止您的组件。在这种情况下,使用Option是不必要的抽象。

如果您的组件在连接失败时仍然存在,您可以这样做:

val maybeConn: Option[Connection] = Option(ConnectionFactory.createConnection(conf))

maybeConn foreach doConnRelatedOperation

doOtherOperationThatDoesNotRequireConn

def doConnRelatedOperation(conn: Connection) = println(conn)
def doOtherOperationThatDoesNotRequireConn = "hello!"

在此代码示例中:

  • Option(ConnectionFactory.createConnection(conf))会返回Some(conn)None(我假设createConnection没有投出;如果可以,那么您可能想要使用而是Try仿函数)
  • 如果maybeConn foreach doConnRelatedOperationmaybeConn,则
  • None将不执行任何操作,或者调用doConnRelatedOperation作为参数的副作用函数Connection maybeConn Some(conn) 1}}是doOtherOperationThatDoesNotRequireConn
  • 请注意,在此示例中,即使没有连接,createConnection也会执行。

<强>最后

假设您的Exception函数可能会抛出Option。在这种情况下,lazy val maybeConn: Try[Connection] = Try(ConnectionFactory.createConnection(conf))是错误的抽象。在这种情况下,您可能希望改为Try(基本上是Option而不是doConnRelatedOperation)。

请注意其他代码不需要修改的美观! doOtherOperationThatDoesNotRequireConn函数仅在创建连接时执行,并且which forever将在之后执行,无论是否有连接。该例外不会影响您的代码流!

欢迎来到Scala的优质部分:)

答案 2 :(得分:0)

使用Option而不是null只是关于scala的“他们说”的事情之一。你的问题是你选择使用那个(相当随机的)建议,而忽略所有其他建议。

在这种情况下更相关的另一条建议是:避免使用状态和可变变量。您可以安全地丢弃“代码1”和“代码2”,然后执行此操作:

lazy val = ConnectionFactory.createConnection(conf)

答案 3 :(得分:0)

{{1}}