假设我有一个方法,session.get(str: String): String但你不知道它是否会返回一个字符串或null,因为它来自Java.
有没有更简单的方法来处理Scala而不是session.get("foo") == null?也许有些魔法适用ToOption(session.get("foo")),然后我可以像Scala一样对待它
ToOption(session.get("foo")) match {
case Some(_) =>;
case None =>;
}
Run Code Online (Sandbox Code Playgroud) 为什么这种结构会导致Scala中出现类型不匹配错误?
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
<console>:6: error: type mismatch;
found : List[(Int, Int)]
required: Option[?]
for (first <- Some(1); second <- List(1,2,3)) yield (first,second)
Run Code Online (Sandbox Code Playgroud)
如果我用List切换Some,它编译得很好:
for (first <- List(1,2,3); second <- Some(1)) yield (first,second)
res41: List[(Int, Int)] = List((1,1), (2,1), (3,1))
Run Code Online (Sandbox Code Playgroud)
这也很好:
for (first <- Some(1); second <- Some(2)) yield (first,second)
Run Code Online (Sandbox Code Playgroud) 我开始探索Scala,我所吸引的一件事就是Option能够消除null相关错误的类型和承诺.
但是,我还没有能够弄清楚如何将列表(或其他集合)Option[String]转换为集合String(显然过滤掉任何值None).
换句话说,我如何从中得到:
List[Option[Int]] = List(Some(1))
Run Code Online (Sandbox Code Playgroud)
......对此:
List[Int] = List(1)
Run Code Online (Sandbox Code Playgroud)
如果这对答案有任何影响,我正在使用Scala 2.8.
如果我有类似的东西List[Option[A]],我想将其转换为a List[A],标准方法是使用flatMap:
scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))
scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)
Run Code Online (Sandbox Code Playgroud)
现在o => o只是一个身份功能.我原以为会有办法:
l.flatMap(Identity) //return a List[String]
Run Code Online (Sandbox Code Playgroud)
但是,我不能让这个工作,因为你不能生成一个object.我试了几件事无济于事; 有没有人有这样的工作?
有没有办法,只使用Scala集合API,在尝试通过索引获取元素时获取List中的Option?
我正在寻找相应的这个功能,它存在吗?
def optionalValue[T](l: List[T], index: Int) = {
if (l.size < (index+1)) None
else Some(l(index))
}
Run Code Online (Sandbox Code Playgroud)
谢谢
为什么使用foreach,map,flatMap等是不是用认为是更好的get斯卡拉选项?如果我使用isEmpty我可以get安全地打电话.
这是一个让事情变得更有效率的机会(对于程序员而言):我觉得不得不把事情包裹起来Some,例如Some(5).这样的事情怎么样:
implicit def T2OptionT( x : T) : Option[T] = if ( x == null ) None else Some(x)
Run Code Online (Sandbox Code Playgroud) 我想知道为什么scala.Option没有fold这样定义的方法:
fold(ifSome: A => B , ifNone: => B)
Run Code Online (Sandbox Code Playgroud)
相当于
map(ifSome).getOrElse(ifNone)
Run Code Online (Sandbox Code Playgroud)
有没有比使用map+ 更好的getOrElse?
使用Scala 2.7.7:
如果我有一个选项列表,我可以使用for-understandness来展平它们:
val listOfOptions = List(None, Some("hi"), None)
listOfOptions: List[Option[java.lang.String]] = List(None, Some(hi), None)
scala> for (opt <- listOfOptions; string <- opt) yield string
res0: List[java.lang.String] = List(hi)
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种风格,宁愿使用HOF.这种尝试过于冗长,无法接受:
scala> listOfOptions.flatMap(opt => if (opt.isDefined) Some(opt.get) else None)
res1: List[java.lang.String] = List(hi)
Run Code Online (Sandbox Code Playgroud)
直觉上我会期望以下工作,但它没有:
scala> List.flatten(listOfOptions)
<console>:6: error: type mismatch;
found : List[Option[java.lang.String]]
required: List[List[?]]
List.flatten(listOfOptions)
Run Code Online (Sandbox Code Playgroud)
即使以下似乎它应该工作,但不是:
scala> listOfOptions.flatMap(_: Option[String])
<console>:6: error: type mismatch;
found : Option[String]
required: (Option[java.lang.String]) => Iterable[?]
listOfOptions.flatMap(_: Option[String])
^
Run Code Online (Sandbox Code Playgroud)
我能想到的最好的是:
scala> listOfOptions.flatMap(_.toList)
res2: List[java.lang.String] = List(hi) …Run Code Online (Sandbox Code Playgroud) 我的代码变得乱七八糟,使用以下代码模式:
val opt = somethingReturningAnOpt
if (opt.isDefinedAt) {
val actualThingIWant = opt.get
}
Run Code Online (Sandbox Code Playgroud)
有没有办法简化这个?(似乎不必要的复杂和代码味道).理想情况下它会是这样的:
if (Some(actualThingIWant) = somethingReturningAnOpt) {
doSomethingWith(actualThingIWant)
}
Run Code Online (Sandbox Code Playgroud)
有可能吗?