簡體   English   中英

Scala:從返回Seq的函數返回一個可變緩沖區

[英]Scala: Returning a mutable buffer from a function that returns a Seq

當我從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是通過Seq特性的約束簡單地引用緩沖區,還是存在實際的底層轉換? 是否最好將值bar視為可變或不可變?

請原諒這個問題是多么開放,但我不覺得我對發生的事情有好的想法,我想改變它。 例如,在從foo返回之前,是否有任何情況下我最好將scalaMutableBuffer轉換scalaMutableBuffer toList

謝謝!

bar被鍵入為Seq [String],它在底層使用可變緩沖區

你是對的, bar的運行時值是一個mutable.ArrayBuffer[String] (因為Buffer本身就是一個特質),而且由於Seq[+A]是一個特征,你作為調用者只能看到“順序“ ArrayBuffer ,盡管你總是可以通過buffer.asInstanceOf[mutable.ArrayBuffer[String]]將其轉換為緩沖區,然后查看緩沖區的實際”內部“。

可能影響Seq操作的性能

當一個暴露Seq[A] ,你暴露了底層集合所遵循的“契約”。 在運行時,它將始終是一個具體的實現。 也就是說,當我們通過apply創建一個Seq

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

具體實現實際上是List[Int]

是否最好將值欄視為可變或不可變?

底層實現是可變的,但通過不可變合同公開。 這意味着當您通過Seq trait的抽象操作緩沖區時,作為調用者沒有可用的可變操作。

例如,當我們這樣做時:

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

抽象保護我們不要讓用戶調用我們不希望他們在運行時類型上執行的操作。

例如,在從foo返回之前,是否有任何情況下我最好將scalaMutableBuffer轉換為toList

我認為這主要是基於意見的。 如果您感覺不到Seq特性,則可以始終使具體類型為不可變。 但請記住,為了讓某人改變Seq的副本,他必須檢查運行時類型並明確地轉換為它 ,並且當你投下所有的賭注時都會關閉。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM