2015-02-06 90 views
1

我想使用返回给定类型的“默认值”的泛型函数。我有一个具有以下情形类结构的帮助下实现这一点:斯卡拉案例类:为类型构造函数生成实例吗?

case class DefaultOp[T](op:() => T) 
implicit val defaultString = DefaultOp[String](() => "") 
implicit val defaultInt = DefaultOp[Int](() => 0) 
implicit val defaultFloat = DefaultOp[Float](() => 0.0f) 
implicit val defaultDouble = DefaultOp[Double](() => 0.0d) 
// ... 

def default[T]()(implicit ev: DefaultOp[T]): T = ev.op() 

这工作正常,但我想扩大它也从一个类型构造结构类型的工作。例如,我想将任何选项类型的默认值设置为“无”,并将任何列表类型设置为无。我如何实现这一点?我的第一个attemt:

implicit val defaultOption = DefaultOp[Option[_]](() => None) 

编译,但它并没有,当我在一个应用程序中使用编译:

error: could not find implicit value for parameter ev: DefaultOp[Option[Float]] 
var test: Option[Float] = default[Option[Float]] 
           ^
one error found 

任何建议,这可怎么做工作?

谢谢!

回答

2

问题是Option[Float]不是Option[_],因为我们不知道_应该是什么。

您可以通过defaultOption一个闪避,并使用类型参数解决这个问题:

implicit def defaultOption[A] = DefaultOp[Option[A]](() => None) 

scala> default[Option[Float]] 
res3: Option[Float] = None 
+0

谢谢!而已。我没有意识到我可以使用函数定义而不是val ...这会导致下一个问题:隐式def defaultDouble与DefaultOp [Double](()=> 0.0d)之间的主要区别是什么?和隐含的val defaultDouble = DefaultOp [Double](()=> 0.0d)?哪一个更好,为什么? – 2015-02-06 18:15:46

+1

唯一的区别是一个是def,另一个是val。对于'defaultDouble',使用val是很好的,因为它永远不会改变。但是,对于泛型类型。 def是必需的,因为您需要能够为(可能)任何类型生成implicits。 – 2015-02-06 18:19:20

+0

还要注意,一个'def'将为每个调用创建一个'DefaultOp'的新实例。如果这是你的关键路径,你可能不想要这个。你可以用这个代码作弊:'private val reusableDefaultOption = DefaultOp [Option [Nothing]](()=> None);隐式def defaultOption [A] = reusableDefaultOption.asInstanceOf [DefaultOp [Option [A]]]'。 – sjrd 2015-02-06 20:03:34