【问题标题】:Scala Option map to another OptionScala 选项映射到另一个选项
【发布时间】:2013-02-17 13:29:35
【问题描述】:

当从一个选项映射时,有没有办法避免在另一个选项中包装一个可能为空的结果。

option.flatMap(arg => Option(arg.somePotentiallyNullValue))

比如

option.optionMap(arg => arg.somePotentiallyNullValue )

我的代码库中只有很多 Java 代码,这意味着永远将映射的结果包装在进一步的 Option 调用中。

【问题讨论】:

  • Maybe (Option) monad。

标签: scala option


【解决方案1】:

从可空类型到Option 的隐式转换怎么样?在范围内的某处声明:

implicit def toOption[T](x: T) : Option[T] = Option(x)

稍后编译器会弄清楚:

option.flatMap(_.somePotentiallyNullValue)

由于flatMap 期望Option[T] 作为结果值,编译器使用toOption 隐式转换,如下所示:

option.flatMap(arg => toOption(arg.somePotentiallyNullValue))

【讨论】:

    【解决方案2】:

    Option 的工厂方法会将null 变成None:

    scala> val os1: Option[String] = Option(null)
    os1: Option[String] = None
    

    附录

    我可能误解了你的问题...

    如果您明智地限制其范围,则可以使用隐式转换:

    scala> implicit def nullable2Option[T >: Null](t: T): Option[T] = if (t == null) None else Some(t)
    warning: there were 1 feature warnings; re-run with -feature for details
    nullable2Option: [T >: Null](t: T)Option[T]
    
    scala> val os2: Option[String] = "foo"
    os2: Option[String] = Some(foo)
    
    scala> val nullS: String = null
    nullS: String = null
    
    scala> val os3: Option[String] = nullS
    os3: Option[String] = None
    

    只要有可用的类型信息供编译器用来驱动尝试将可空类型的值桥接到Option,这将起作用。例如,调用方法时(类型总是显式的)。

    【讨论】:

      【解决方案3】:

      为了让事情变得更简单,你可以引入一个新类型:

      implicit class CheckedOption[T](val option:Option[T])
      
      object CheckedOption {
        @inline implicit def toOption[T](checkedOption:CheckedOption[T]):Option[T] =
          checkedOption.option.flatMap(Option.apply)
      }
      

      然后在您的代码中,在您使用选项实例的地方执行以下操作:

      def use(o:CheckedOption[String]) = {
        o map { value =>
          value + "-Some"
        } getOrElse "None"
      }
      
      val option1:Option[String] = Some(null)
      val option2:Option[String] = Some("foo")
      
      use(option1) //> res0: String = None
      use(option2) //> res1: String = foo-Some
      

      【讨论】:

        猜你喜欢
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-12
        • 1970-01-01
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多