我想要一个功能扩展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
,而其他任何事情都没有。在所有其他方面,MahThing
加List
就像folder1, folder2,folder3
一样。
答案 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以避免开销。
但是,我不建议您在MahDouble
和Double
之间进行隐式转换,因为它太难以预测,而且很难理解发生了什么,见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
^
显示未转换其他列表类型。