提问人:Chris Beck 提问时间:1/6/2017 更新时间:1/8/2017 访问量:64
从 Scala 中的 mutable.traversable 类型生成 mutable.seq
Yield mutable.seq from mutable.traversable type in Scala
问:
我有一个类型的变量underlying
Option[mutable.Traversable[Field]]
我想在我的课堂上做的就是提供一种方法,以以下方式将其作为 Sequence 返回:
def toSeq: scala.collection.mutable.Seq[Field] = {
for {
f <- underlying.get
} yield f
}
这失败了,因为它抱怨不符合 .它所做的只是产生字段类型的东西 - 在我看来这应该有效吗?mutable.traversable
mutable.seq
一个可能的解决方案是:
def toSeq: Seq[Field] = {
underlying match {
case Some(x) => x.toSeq
case None =>
}
}
虽然我不知道调用x.toSeq时实际发生了什么,但我想这里使用了更多的内存来完成此操作。
如能提供解释或建议,将不胜感激。
答:
我很困惑为什么你说“我想这里使用的内存比实际需要完成的要多”。Scala 在执行时不会复制您的值,它只是创建一个新的值,该值将具有指向指向的相同值的指针。由于这个新结构正是你想要的,所以无法避免与额外指针相关的额外内存(但额外内存量应该很小)。有关更深入的讨论,请参阅有关持久性数据结构的 wiki。Field
x.toSeq
Seq
Field
underlying
关于您可能的解决方案,可以稍作修改以获得您期望的结果:
def toSeq : Seq[Field] =
underlying
.map(_.toSeq)
.getOrElse(Seq.empty[Field])
此解决方案将返回一个空的 if ,它比您使用 .我说它“更安全”,因为如果 Option 是 a,则会抛出 a,而 my 永远不会返回有效值。Seq
underlying
None
get
get
NoSuchElementException
None
toSeq
功能方法
顺便说一句:当我第一次开始用scala编程时,我会编写许多形式的函数:
def formatSeq(seq : Seq[String]) : Seq[String] =
seq map (_.toUpperCase)
这不太实用,因为您期望特定的集合类型,例如 在 .formatSeq
Future
我发现更好的方法是写:
def formatStr(str : String) = str.toUpperCase
或者我首选的编码风格:
val formatStr = (_ : String).toUpperCase
然后,您的函数的用户可以以他们想要的任何方式应用,您不必担心所有集合的投射:formatStr
val fut : Future[String] = ???
val formatFut = fut map formatStr
val opt : Option[String] = ???
val formatOpt = opt map formatStr
评论