Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何扩展列表[双精度]_Scala_Implicit Conversion_Implicit - Fatal编程技术网

Scala 如何扩展列表[双精度]

Scala 如何扩展列表[双精度],scala,implicit-conversion,implicit,Scala,Implicit Conversion,Implicit,我想要一个自定义类,它在功能上扩展了List[Double],并添加了一些功能。我对《拉皮条客我的图书馆》的理解将引导我构建如下内容: implicit class MahThing(list:List[Double]) { def mahStuff = ... } 问题是,现在只要导入MahThing,所有List[Double]s都可以选择执行MahThing 同: class MahThing(list:List[Double]) { def mahStuff ... }

我想要一个自定义类,它在功能上扩展了
List[Double]
,并添加了一些功能。我对《拉皮条客我的图书馆》的理解将引导我构建如下内容:

implicit class MahThing(list:List[Double]) {
    def mahStuff = ...
}
问题是,现在只要导入
MahThing
,所有
List[Double]
s都可以选择执行
MahThing

同:

class MahThing(list:List[Double]) {
    def mahStuff ...
}
implicit def toThing(list:List[Double]) = new MahThing(list)
现在,
list.toThing
产生
mahting
,但是
mahting
不能做
list
y的东西。在
mahting
中将
List
操作定义为
List是很费劲的。操作
是很费劲的。出于某种原因,在使用
mahting
的实例时,我会在
map
操作期间声明变量类型


我真正需要的是扩展
List[Double]
的确切功能。本来应该是
MahThing
的事情可以去做
MahThing
,而没有其他人去做。Plus
MahThing
在其他各方面都像一个
List

使用隐式转换是扩展List[T](在您的例子中,T是双倍)功能(作为List[T]final,不能扩展)的正确方法,正如您所看到的

无论何时导入MahThing,所有列表[Double]都可以选择 做点什么

但是,如果我没有弄错的话,您不希望所有的List[Double]都是这样的,所以我的建议是创建一个MahDouble类,它将接受Double作为参数,并隐式地将这两种方式转换为Double

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

case class MahDouble(d: Double)
然后,您可以将该mahdool用作mahting列表的类型,并隐式地从List[mahdool]转换它

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

case class MahThing(list:List[MahDouble]) {
   def mahStuff ...
}
对于任何方面,Mahdool都将起作用并成为Double,但只有由Mahdool元素组成的列表才能获得mahStuff方法

val mahDoubleList: List[MahDouble] = List(2.0, 3.0, 4.0, 5.0)
问候,,
Alessandro.

正如@Alessandro G.所建议的,最好的方法是为
Mahdool
创建特殊类型-而不是整个
列表

case class MahDouble(d: Double) extends AnyVal
扩展AnyVal
可以避免开销

但是,我不建议您在
MahDouble
Double
之间进行隐式转换,因为这太不可预测,而且很难理解发生了什么,请参阅

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

 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列表,也可以转换为mah列表:

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)

以下是我如何看待隐式转换的工作方式。首先,隐式类:

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
                   ^
scala>val strs=“foo”::“bar”::无
strs:List[String]=List(foo,bar)
scala>strs.mahStuff
:13:错误:值不是列表[字符串]的成员
沙丁鱼
^

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

您可以添加另一个隐式转换-从
MahThing
list[Double]
您实际想做什么?
列表
mahting
的实现细节吗?您是否希望
list
是可变的,这样做
mahting.list.somemutatinglist操作(…)
是不可行的?@BrianKent,我想做
mahtuff
!主要是对清单做出保证。。。断言属性。。。诸如此类。为了扩展这句话,
MahThing
是一个
列表,只是一个包含附加功能的列表。@Shadowlands你能把它写下来作为一个答案,表明它做了我想要的吗?如上所述,我在导入
隐式类mahtool
的任何地方都会遇到问题,因为我将
mahtool
提供给所有
List
s。
mahtool
可能是一个值类:
case类mahtool(d:Double)扩展了AnyVal
。我不建议在
Double
mahDouble
之间进行隐式转换-这太不可预测了(请参阅JavaConvertions vs JavaConverters主题以获取论证)。最好的方法是隐式添加clear方法:
val mahDoubleList=List(2.0.mah,3.0.mah,4.0.mah,5.0.mah)
,您可以在这里摆脱显式类型,顺便说一句。@dk14获得了它,很高兴知道我可以这样做。谢谢:)@AlessandroG。谢谢你对这方面的见解。用
def mahStuff=println(“sup”)
粘贴你写的所有东西,我无法
mahStuff.mahStuff
。想什么?@WalrustheCat欢迎你。您是否碰巧遇到了类似“value mahStuff不是列表[MahDouble]的成员”这样的错误?如果是这样的话,记得在需要使用的地方添加import MahThingMahThing@AlessandroG. 一定是这样,一切似乎都正常运转。谢谢。很酷,但是所有的
List[Double]
s都被转换了吗?是的,只要-对于该列表-隐式转换是嘿,我很感谢你对这一点的理解,但它并不是在功能上扩展List[Double]。考虑到上面的代码:
List(1.0)map{{{uu.mah}map{{uu+1}
@mahdoole可以是一个函子,如果您需要对其进行变异,只需添加映射操作(基于复制方法),或者只需使用“map{.d+1}map{.mah}”。除包装或包装外的其他解决方案通常不安全。