首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scala中从mutable.traversable类型生成mutable.seq

在Scala中从mutable.traversable类型生成mutable.seq
EN

Stack Overflow用户
提问于 2017-01-06 18:12:50
回答 1查看 54关注 0票数 0

我有一个Option[mutable.Traversable[Field]]类型的变量underlying

我想在我的类中做的所有事情就是提供一个方法,以如下方式将其作为序列返回:

代码语言:javascript
复制
def toSeq: scala.collection.mutable.Seq[Field] = {
  for {
    f <- underlying.get
  } yield f
}

这会失败,因为它会抱怨mutable.traversable不符合mutable.seq。它所做的就是产生Field类型的东西--在我看来,这应该是可行的?

一种可能的解决方案是:

代码语言:javascript
复制
def toSeq: Seq[Field] = {
  underlying match {
    case Some(x) => x.toSeq
    case None =>
  }
}

虽然我不知道当x.toSeq被调用时实际发生了什么,我想这里使用了更多的内存来完成这一任务。

如果您能给我一个解释或建议,我们将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2017-01-06 20:45:07

我不明白为什么你会说“我想这里使用的内存比实际需要的要多”。在执行x.toSeq时,Scala不会复制您的Field值,它只是创建一个新的Seq,它将具有指向underlying所指向的相同Field值的指针。由于这种新结构正是您想要的,因此无法避免与额外指针相关的额外内存(但额外内存的数量应该很小)。有关更深入的讨论,请参阅persistent data structures上的维基。

关于您可能的解决方案,可以稍微修改一下,以获得您期望的结果:

代码语言:javascript
复制
def toSeq : Seq[Field] = 
  underlying
    .map(_.toSeq)
    .getOrElse(Seq.empty[Field])

如果underlying是一个比使用get的原始尝试更安全的None,则此解决方案将返回一个空的Seq。我之所以说它“更安全”,是因为如果选项是一个NoSuchElementExceptionget就会抛出一个None,而我的toSeq总是会返回一个有效的值。

函数式方法

作为附注:当我第一次开始使用scala编程时,我会编写许多如下形式的函数:

代码语言:javascript
复制
def formatSeq(seq : Seq[String]) : Seq[String] = 
  seq map (_.toUpperCase)

这不太有用,因为你期望的是一个特定的集合类型,例如formatSeq不能在Future上工作。

我发现更好的方法是这样写:

代码语言:javascript
复制
def formatStr(str : String) = str.toUpperCase

或者我更喜欢的编码风格:

代码语言:javascript
复制
val formatStr = (_ : String).toUpperCase

然后你的函数的用户可以以任何他们想要的方式应用formatStr,你不必担心所有的集合类型转换:

代码语言:javascript
复制
val fut : Future[String] = ???
val formatFut = fut map formatStr

val opt : Option[String] = ???
val formatOpt = opt map formatStr
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41503388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档