我想知道这里的原因是什么(implicit ev: Null <:< A1):
sealed abstract class Option[+A] extends Product with Serializable {
def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
...
}
Run Code Online (Sandbox Code Playgroud)
岂不
def orNull[A]: A = this getOrElse null
Run Code Online (Sandbox Code Playgroud)
考虑到它似乎甚至不适用于像这样的值类型
Option(1).orNull
Run Code Online (Sandbox Code Playgroud)
但
Option(1).getOrElse(null)
Run Code Online (Sandbox Code Playgroud)
呢?
Option的源代码
在Scala中,当我想要设置某些东西时None,我有几个选择:使用None或Option.empty[A].
我应该选择一个并持续使用它,还是有时候我应该使用一个而不是另一个?
例:
scala> def f(str: Option[String]) = str
f: (str: Option[String])Option[String]
scala> f(None)
res0: Option[String] = None
scala> f(Option.empty)
res1: Option[String] = None
Run Code Online (Sandbox Code Playgroud) 作为文章的结果,我读到了Option有助于避免NullPointerException的类,我开始在整个地方使用它.想象一下这样的事情:
var file:Option[File] = None
Run Code Online (Sandbox Code Playgroud)
以后当我使用它时:
val actualFile = file.getOrElse(new File("nonexisting"))
if(actualFile.getName.equals("nonexisting")) { // instead of null checking
}
else { // value of file was good
}
Run Code Online (Sandbox Code Playgroud)
做这样的事情对我来说感觉不那么"正确".我也注意到.get已经被弃用了..这种东西是你们用Option做的,或者我走错了路?
我有几种计算价值的方法,优先级递减.
firstWay()
second() + way()
orA(thirdWay())
Run Code Online (Sandbox Code Playgroud)
每个都返回一个Option.我想"合并"这些并获得第一个Option返回的值Some,或者None如果全部返回None.
当然,如果firstWay()返回a Some,我不应该计算其余的.
什么是最惯用(或至少是合理可读)的方式?
这个问题的答案表明,Scala中Option的fold方法是一种catamoprhism.从维基百科中,一个catamophism是"从初始代数到其他代数的独特同态.这个概念已经应用于函数式编程作为折叠".所以这似乎是公平的,但引导我将初始代数作为F-代数类别中的初始对象.
因此,如果Option上的折叠实际上是一个catamophism,那么需要有一些仿函数F来创建F代数的类别,其中Option将是初始对象.我无法弄清楚这个仿函数是什么.
对于类型列表,A仿函数F是F[X] = 1 + A * X.这是有道理的,因为List是一个递归数据类型,所以如果X是,List[A]那么上面读取的类型列表A是空列表(1),或(+)a 和a的一对(*).但Option不是递归的.只会(没什么或一个).所以我没看到仿函数在哪里.AList[A]Option[A]1 + AA
只是要清楚,我认识到,期权已经是一个仿函数,因为它需要A给Option[A],但是什么名单做是不同的,A是固定的,仿函数是用来描述如何构建递归的数据类型.
在一个相关的说明中,如果它不是一个catamorphism它可能不应被称为折叠,因为这会导致一些混乱.
scala category-theory catamorphism scala-option recursion-schemes
我试图找出重构以下代码以消除 Option.get() 的使用的最佳方法。我知道使用 get 方法被认为是不好的做法。
if (myConnection.isDefined) {
myConnection.get.close
}
Run Code Online (Sandbox Code Playgroud)
其中 myConnection 的类型为 Option[Connection]
getOrElse 似乎不起作用,因为没有“else”对象可以调用该方法。如果 myConnection 是 None,那么我不想做任何事情。
我想我可以使用 forEach 像:
myConnection.foreach{ c => c.close }
Run Code Online (Sandbox Code Playgroud)
这可行,但对我来说看起来很奇怪。就我而言,myConnection 永远不会包含多个连接,其他人稍后查看我的代码可能会相信它可以包含多个连接。
有没有更好的方法来做到这一点既简洁又清晰?
似乎嵌套匹配不起作用,这是一个奇怪的限制.
行为的一个例子如下:
Some(Some(1),2) match {
| case Some(Some(a),b) => a
| case e => e
| }
<console>:9: error: wrong number of arguments for <none>: (x: (Some[Int], Int))Some[(Some[Int], Int)]
case Some(Some(a),b) => a
^
<console>:9: error: not found: value a
case Some(Some(a),b) => a
^
Run Code Online (Sandbox Code Playgroud)
这有效:
Some(Some(1),2) match {
case Some(a) => a match {
case (Some(a),b) => "yay"
case e => "nay"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我只是一个蠢货还是有更好的方法来实现这一目标?
我有一些需要调用Java API的Scala代码
Java API接受可能为null的参数.我的Scala当然使用了Option.
举例来说,假设我有一个Java对象的构造Foo(Integer),其中Integer可能null.我想给Scala打电话bar: Option[Int].
我试过这个
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
val foo = Foo( bar.getOrElse(null) )
Run Code Online (Sandbox Code Playgroud)
但得到了这个编译错误
Error:(335, 44) type mismatch;
found : Any
required: Integer
bar.getOrElse(null),
Run Code Online (Sandbox Code Playgroud)
这样做的正确习惯是什么?
2种启动Option对象的方式的优缺点是什么:
1.
def getAmount: Option[Int] = {
val a: Int = 1
Option(a)
}
Run Code Online (Sandbox Code Playgroud)
2.
def getAmount: Option[Int] = {
val a: Int = 1
Some(a)
}
Run Code Online (Sandbox Code Playgroud)
我应该使用哪个?
scala ×10
scala-option ×10
case ×1
catamorphism ×1
coalescing ×1
extractor ×1
implicit ×1
java-api ×1
null ×1
parameters ×1