如何工作选择单?我正在浏览 Scala API 还有一个例子(我的意思是第二个),

由于理解的工作方式,如果没有从请求返回。

但是,当我尝试此代码时:

 val upper = for {
   name <- None //request.getParameter("name")
   trimmed <- Some(name.trim)
   upper <- Some(trimmed.toUpperCase) if trimmed.length != 0
 } yield upper
 println(upper.getOrElse(""))

我会收到编译错误。这应该如何工作?

有帮助吗?

解决方案

因此,您会发现编译器错误

  name <- None

这样, None 设定为 None.type 和变量 name 推断为类型 Nothing. 。 (也就是说,如果实际存在,它将具有这种类型,但显然是在运行时甚至没有创建它。)因此,没有方法 name.trim 存在,它不会编译。

如果你有 request.getParameter("name") 可用,它的类型是 Option[String], name 可能有类型 Stringname.trim 会编译。

您可以通过指定类型来解决此问题 None:

  name <- None: Option[String]

其他提示

为了扩展凯文的答案,您可以避免包装值 Some() 通过使用 = 操作员而不是 <- 操作员:

val upper = for {
   name <- None: Option[String] //request.getParameter("name")
   trimmed = name.trim
   upper = trimmed.toUpperCase if trimmed nonEmpty
} yield upper

坦白的理解会编译到与凯文的版本非常相似的内容,但我经常发现使用更清楚地使用 mapfilter 明确避免杂乱(例如额外的可变名称),这些名称对表达的语义内容没有任何添加。

要扩展Debilski的答案,您也无需明确将后续值包装在 Some(), ,您实际映射的唯一值是原始的 name.

更好的方法是使用 mapfilter 直接进行操作,而不是出于理解:

注意:在幕后,Scala编译器将转换为MAP/FLATMAP/过滤器的组合,因此这种方法永远不会比透明度的效率更低,并且很可能会更有效

def clean(x:Option[String]) = x map { _.trim.toUpperCase } filterNot { _.isEmpty }

val param = None : Option[String] // request.getParameter("name")
println( clean(param).getOrElse("") )
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top