Scala Option隐式转换 - 不良做法或缺少功能?

ssc*_*zio 2 scala domain-model implicit-conversion

我将我的数据模型表示为案例类,键入可能为null的值作为Option.

case class Document(id: Long, title: String, subtitle: Option[String])
Run Code Online (Sandbox Code Playgroud)

现在我尝试实例化case类:

Document(123, "The Title", "Subtitle") // Doesn't work
Run Code Online (Sandbox Code Playgroud)

但是NOPE!这不起作用,我必须将可选值包装在Some中.

Document(123, "The Title", Some("Subtitle")) // Works
Run Code Online (Sandbox Code Playgroud)

Scala对于类型一般非常聪明,但为什么硬编码文字或(任何字符串)与null/None不同,这是不言自明的?

通过添加这种隐式转换,我能够解决这个问题并使Scala"更加聪明"

implicit def autoSome[T](any:T) = Some(any)
Document(123, "The Title", "Subtitle") // Now it works!
Run Code Online (Sandbox Code Playgroud)

问题:我是唯一一个应该提供隐式转换的语言T - > Some(T)开箱即用吗?或者是否有任何我不知道的问题是默认情况下如此广泛隐含?

whe*_*ies 5

这可能导致无数问题.这里的问题不是你可能想到的,而是你认为不会发生的事情.也就是说,如果你创建另一个适用于Option类型的隐式类,你最终可能会创建一个你从未想过要发生的人为结果,即你的重载类型的运算符出现在你的非重载类型中.

 implicit class OptDouble(opt: Option[Double]) extends Any{
   def *(x: Double) = Some((opt getOrElse 0.0) * x)
   def ^(x: Double) = Some(Math.power(opt getOrElse 1.0, x))
 }

 val z = q^4.5
Run Code Online (Sandbox Code Playgroud)

类型zOption[Double].您不希望发生这种情况,但首先Scala执行了隐式转换Option,然后使用隐式类来调用^运算符.现在,看着你的代码的人们会想到他们为什么会这样做Option.你可能会开始x getOrElse 0.0在代码周围看到一些防御措施,因为人们会争先恐后地Option离开(是的,这来自个人经验.)

那就是说,你应该做的是apply在对象上使用另一个:

object Document{
  def apply(id: Long, title: String, subtitle: String) = new Document(id, title, Some(subtitle))
}
Run Code Online (Sandbox Code Playgroud)

它会做你想要的,只要你没有为定义的默认情况下它做的一切subtitle,即subtitle: Option[String] = None.