gpt4 book ai didi

java - Scala:从返回 Seq 的函数返回可变缓冲区

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:17 26 4
gpt4 key购买 nike

当我从 Java List 转换为通用 Scala Seq 时,我想更好地理解这段代码中实际发生的事情:

import scala.collection.JavaConverters._

def foo(javaList: java.util.List[String]): Seq[String] = {
val scalaMutableBuffer: mutable.Buffer[String] = javaList.asScala
scalaMutableBuffer
}

...

val bar = foo(someJavaList)

我的理解是否正确,虽然 bar 被键入为 Seq[String],但它在底层使用可变缓冲区,可能会影响序列操作? Seq 是通过 Seq 特征的约束简单地引用缓冲区,还是存在实际的底层转换?最好将 bar 包含的值视为可变的还是不可变的?

请原谅这个问题的开放性,但我觉得我不太了解正在发生的事情,我想改变它。例如,在从 foo 返回之前转换 scalaMutableBuffer toList 是否会更好?

谢谢!

最佳答案

while bar is typed as a Seq[String], it's using a mutable buffer on an underlying level

没错,bar 的运行时值是一个 mutable.ArrayBuffer[String](因为 Buffer 是一个 trait本身),并且由于 Seq[+A] 是一个特征,作为调用者,您只能看到 ArrayBuffer 的“序列”部分,尽管您总是可以强制转换它通过 buffer.asInstanceOf[mutable.ArrayBuffer[String]] 发送到缓冲区,然后查看缓冲区的实际“内部结构”。

potentially affecting the performance of Seq operations

当公开一个 Seq[A] 时,您公开了底层集合所遵循的“契约”。在运行时,它总是一个具体的实现。即,当我们通过 apply 创建一个 Seq 时:

scala> Seq(1,2,3)
res0: Seq[Int] = List(1, 2, 3)

具体实现其实是一个List[Int]

Would it be best to think of the value bar contains as mutable or immutable?

底层实现是可变的,但通过不可变合约公开。这意味着当您通过 Seq 特征的抽象对缓冲区进行操作时,作为调用者您没有可用的可变操作。

例如,当我们这样做时:

scala> val bufferAsSeq: Seq[Int] = scala.collection.mutable.Buffer(1,2,3)
bufferAsSeq: Seq[Int] = ArrayBuffer(1, 2, 3)

scala> bufferAsSeq += 4
<console>:12: error: value += is not a member of Seq[Int]
bufferAsSeq += 4

抽象防止我们让用户调用我们不希望他们在运行时类型上执行的操作。

For example, would there be any cases in which it would be preferable for me to convert scalaMutableBuffer toList before returning from foo

我认为这主要是基于意见。如果您感觉不到 Seq 特性,您始终可以让具体类型不可变。但是请记住,为了让某人改变 Seq 的副本,他必须检查运行时类型并显式地转换为它,并且当您进行所有操作时关闭。

关于java - Scala:从返回 Seq 的函数返回可变缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39138133/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com