如何扩展List [Double]

时间:2015-09-02 21:09:22

标签: scala implicit-conversion implicit

我想要一个功能扩展List[Double]的自定义类,并添加一些功能。我对 皮条客我的图书馆 的理解会让我构建这样的东西:

implicit class MahThing(list:List[Double]) {
    def mahStuff = ...
}

问题是,现在导入MahThing的所有地方List[Double]都可以选择mahStuff

同样:

class MahThing(list:List[Double]) {
    def mahStuff ...
}
implicit def toThing(list:List[Double]) = new MahThing(list)

现在,list.toThing生成MahThing,但MahThing无法生成List个内容。在List中精心定义MahThing作为list.operation的操作是艰苦的。出于某种原因,使用MahThing的实例,它正在使我成为在map操作期间声明变量类型。

我真正需要的是扩展List[Double]的确切功能。那些应该是MahThing的事情可以做mahStuff,而其他任何事情都没有。在所有其他方面,MahThingList就像folder1, folder2,folder3 一样。

3 个答案:

答案 0 :(得分:2)

使用隐式转换是扩展List [T](在你的情况下T为Double)功能的正确方法(正如List [T] final,它无法扩展)并且如你所见

  

导入MahThing的所有地方,所有List [Double]都可以选择   做mahStuff。

但是,如果我做对了,你不希望所有List [Double]都是这样的,所以我的建议是创建一个MahDouble类,它接受一个Double as参数并隐式地将两种方式转换为Double < / p>

object MahDouble {
   implicit def toMah(d: Double): MahDouble = new MahDouble(d)
   implicit def backToDouble(m: MahDouble): Double = m.d
}

case class MahDouble(d: Double)

然后您可以将MahDouble用作MahThing列表的类型,并隐式地将其从List [MahDouble]转换。

object MahThing {
   implicit def toThing(list:List[MahDouble]): MahThing = new MahThing(list)
}

case class MahThing(list:List[MahDouble]) {
   def mahStuff ...
}

对于任何方面,MahDouble将扮演并成为Double,但只有由MahDouble元素组成的列表才会获得mahStuff方法

val mahDoubleList: List[MahDouble] = List(2.0, 3.0, 4.0, 5.0)

此致 的Alessandro。

答案 1 :(得分:1)

正如@Alessandro G.建议最好的方法是为MahDouble创建特殊类型 - 而不是整个List

case class MahDouble(d: Double) extends AnyVal

extends AnyVal会为您提供value class以避免开销。

但是,我不建议您在MahDoubleDouble之间进行隐式转换,因为它太难以预测,而且很难理解发生了什么,见this article

但你仍然可以为你的特殊双打添加漂亮的构造函数:

 implicit class RichDouble(d: Double){
    def mah = MahDouble(d)
 }

这是列表的类型类:

 implicit class RichMaxDoubleList(l: List[MahDouble]){
    def mahStuff = "done"
 }

现在你可以使用它了:

 scala> val l = List(1.0 mah, 2.0 mah)
 l: List[MahDouble] = List(MahDouble(1.0), MahDouble(2.0))

 scala> l.mahStuff
 res7: String = done

您可以将常规列表转换为mah&s列表并返回:

scala> List(1.0, 2.0).map(_.mah)
res8: List[MahDouble] = List(MahDouble(1.0), MahDouble(2.0))

scala> res8.map(_.d)
res9: List[Double] = List(1.0, 2.0)

答案 2 :(得分:0)

以下是我看到隐式转化工作的方式。首先是隐式类:

implicit class MahThing(val list: List[Double]) {
   def mahStuff = {
     // ...do your checks
     this // to ensure we get the object back so I can chain list-like functions off it to prove it has been converted back.
   }
}

和反向隐式def转换回列表:

implicit def thing2list(thing: MahThing): List[Double] = thing.list

应用于双重列表:

scala> dbs.mahStuff
res1: MahThing = MahThing@35e06c5d

scala> dbs.mahStuff.tail
res2: List[Double] = List(0.45)

对tail的调用表明MahStuff实例很容易转换回列表。

现在尝试使用字符串列表:

scala> val strs = "foo" :: "bar" :: Nil
strs: List[String] = List(foo, bar)

scala> strs.mahStuff
<console>:13: error: value mahStuff is not a member of List[String]
              strs.mahStuff
                   ^

显示未转换其他列表类型。