只要我们有一个PartialFunction[X,R]很容易将它转换为返回的函数Option[R],例如
def pfToOptf[X, R](f: PartialFunction[X,R])(x: X) =
if (f.isDefinedAt(x)) Some(f(x))
else None
Run Code Online (Sandbox Code Playgroud)
但是,如果任务相反,那该怎么办:假设我有一个函数作为参数f获取X并返回Option[R]结果.我想做出一个PartialFunction[X,R].什么是最好的方法?
我想出来的东西看起来很丑陋我的口味:
def optfToPf[X,R](f: X => Option[R]) : PartialFunction[X,R] = {
object extractor {
def unapply(x: X): Option[R] = f(x)
}
{ case extractor(r) => r }
}
Run Code Online (Sandbox Code Playgroud)
我错过了一些更好的方法吗?
我正在使用Option Type的isEmpty方法来检查是否没有值.我不想case match在我的情况下使用as,我只是想检查是否有,None因为我会向调用者抛出错误.但isEmpty即使值很大,该方法也会失败None.
这是我试过的!
val questionOption = Question.getQuestionForQuestionId(userExam.get.examId, currQuesId + 1)
if(questionOption.isEmpty) {
Left(Failure(FailureCode.NO_DATA_FOUND, "Cannot get next exam question you tampered your cookie or cookie is lost.... >> TODO... modify the exception message"))
}
Run Code Online (Sandbox Code Playgroud)
它没有进入if条件.我试着在questionOption上做一个println,然后打印出None.所以想知道为什么我没有进入if条件.
最后,本文介绍了新的Java 8 Optional,并指出
可选项并不像Scala中的Option [T]那么强大(但至少它不允许包装null).API不像null处理那么简单,可能要慢得多.但编译时检查的好处加上可选性的可读性和文档值始终大大优于劣势
我对Scala有一个非常基本的了解,并且我熟悉Java 8 Optional,所以初看起来,我不清楚两者之间有什么区别,如果有的话.
我知道,例如,在Scala中我可以使用模式匹配来测试Option并让我的生活更轻松.但是,排除Scala语法的特性,我想知道Option在Scala中是否可以用OptionalJava 做些什么.
希望这不是一个愚蠢的问题,但每当我读到"强大的"时,问号就会浮现在我的头上.
我正在尝试编写一个函数,当它们以通用方式包装在Option中时,重用我对Object A - > Object B的隐式转换,以便Option [A] - > Option [B]转换也工作.
我想出的是:
implicit def fromOptionToOption[A, B](from: Option[A])(implicit conversion: (A) => B): Option[B] = from.map(conversion(_))
Run Code Online (Sandbox Code Playgroud)
当我将一个(..)分配给一个值而不是当我分配一个Option val时,这是有效的; 请参阅以下控制台输出:
scala> trait T
defined trait T
scala> case class Foo(i: Int) extends T
defined class Foo
scala> case class Bar(i: Int) extends T
defined class Bar
scala> implicit def fromFooToBar(f: Foo):Bar = Bar(f.i)
fromFooToBar: (f: Foo)Bar
scala> implicit def fromBarToFoo(b: Bar):Foo = Foo(b.i)
fromBarToFoo: (b: Bar)Foo
scala> implicit def fromOptionToOption[A, B](from: Option[A])(implicit conversion: …Run Code Online (Sandbox Code Playgroud) 这基本上是为了包装java工厂方法,如果无法根据输入创建项目,则抛出异常.我正在寻找基础库中的东西,如:
def exceptionToOption[A](f: => A):Option[A] ={
try{
Some(f)}
catch{
case e:Exception => None}
}
Run Code Online (Sandbox Code Playgroud)
用法:
val id:Option[UUID] = exceptionToOption(UUID.fromString("this will produce None"))
Run Code Online (Sandbox Code Playgroud)
我知道我可以自己写,但我想检查一下,我不是在重新发明轮子.
如何(最好)将方法调用返回的选项转换为Try(优先级,尽管Either或scalaz \/甚至验证可能没问题),包括在适当的情况下指定Failure值?
例如,我有以下代码,感觉很笨,但至少做(大部分)工作:
import scala.util._
case class ARef(value: String)
case class BRef(value: String)
case class A(ref: ARef, bRef: BRef)
class MismatchException(msg: String) extends RuntimeException(msg)
trait MyTry {
// Given:
val validBRefs: List[BRef]
// Want to go from an Option[A] (obtained, eg., via a function call passing a provided ARef)
// to a Try[BRef], where the b-ref needs to be checked against the above list of BRefs or fail:
def getValidBRefForReferencedA(aRef: ARef): Try[BRef] = {
val abRef = for { …Run Code Online (Sandbox Code Playgroud) Scala中是否存在预定义函数x,它将2个选项组合在一起
Some(a) x None => Some(a)
None x Some(b) => Some(b)
None x None => None
Run Code Online (Sandbox Code Playgroud) Option可以隐式转换为Iterable- 但为什么它不只是直接实现Iterable:
def iterator = new Iterator[A] {
var end = !isDefined
def next() = {
val n = if (end) throw new NoSuchElementException() else get
end = true
n
}
def hasNext = !end
}
Run Code Online (Sandbox Code Playgroud)
编辑: 事实上它甚至比那更糟糕,因为在2.8 Option中声明了一个iterator方法:
def iterator: Iterator[A] =
if (isEmpty) Iterator.empty else Iterator.single(this.get)
Run Code Online (Sandbox Code Playgroud) 可以说我有一个像这样的数组*:
val foo: Any = 1 : Int
Option(foo.asInstanceOf[String])
Run Code Online (Sandbox Code Playgroud)
由于显而易见的原因失败:
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Run Code Online (Sandbox Code Playgroud)
接下来让我们考虑以下类:
case class DummyRow() {
val foo: Any = 1 : Int
def getAs[T] = foo.asInstanceOf[T]
def getAsOption[T] = Option(foo.asInstanceOf[T])
}
Run Code Online (Sandbox Code Playgroud)
至于我可以告诉大家getAs应该的行为方式与以前一样apply,然后asInstanceOf.
令人惊讶的是事实并非如此.单独调用时会抛出异常:
DummyRow().getAs[String]
// java.lang.ClassCastException: java.lang.Integer cannot be cast to
// java.lang.String
// ... 48 elided
Run Code Online (Sandbox Code Playgroud)
但当Option成功包装时:
val stringOption = Option(DummyRow().getAs[String])
// Option[String] = Some(1)
DummyRow().getAsOption[String]
// Option[String] …Run Code Online (Sandbox Code Playgroud) generics scala classcastexception scala-option scala-generics
我有一个列表l:List[T1],目前我正在做以下事情:
myfun : T1 -> Option[T2]
val x: Option[T2] = l.map{ myfun(l) }.flatten.find(_=>true)
Run Code Online (Sandbox Code Playgroud)
该myfun函数返回None或Some,flatten抛弃所有None,并且find返回列表的第一个元素(如果有的话).
这对我来说似乎有些苛刻.我认为可能存在一些理解或类似的东西会减少浪费或更聪明.例如:我不需要如有后续的答案myfun返回任何 Some在map列表中l.