2012-03-17 37 views
21

10 satır içeren bir dosyam var - onu almak istiyorum ve sonra bunları yeni satır ("\ n") sınırlayıcıyla bölüyorum.Scala'da toString ve mkString arasındaki fark nedir?

burada

val data = io.Source.fromFile("file.txt").toString; 

yaptık Ama satırbaşıyla dosyayı bölmek için çalışırken bu hataya neden olur.

Sonra
val data = io.Source.fromFile("file.txt").mkString; 

denedik Ve işe yaradı.

Ne var ne yok? Birisi bana iki yöntem arasındaki farkın ne olduğunu söyleyebilir mi?

+13

FYI, hiç kimse bu noktalı virgülleri satırın sonunda yazmaz. –

+0

İlgili dokümanları bulmakta sorun mu yaşıyorsunuz? Tam olarak ne fark olduğunu söylerler. İlk adım, bunları yerel dosya sisteminizde bulmak ve tarayıcınızda yer işareti koymaktır. –

+4

Truthfully, 'toString' bir hata ayıklama yöntemidir. Gerçek amaç, tüm nesneleri yazdırılabilir yapmaktır, böylece hata ayıklama mesajları/hata ayıklayıcıları bir şey gösterebilir. –

cevap

23

toString yönteminin bir nesnenin dize temsilini döndürmesi beklenir. Anlamlı bir sunum sağlamak çoğu zaman geçersiz kılınır. MkString yöntemi, koleksiyonlar üzerinde tanımlanır ve sağlanan dizgeyle koleksiyonun öğelerini birleştiren bir yöntemdir. Örneğin,

val a = List("a", "b", "c") 
println(a.mkString(" : ")) 

gibi bir şey deneyin ve çıktı olarak "a: b: c" alırsınız. MkString yöntemi, koleksiyonun öğelerini sağladığınız dizeyle birleştirerek koleksiyonunuzdan bir dizi oluşturdu. Gönderdiğiniz özel durumda, mkString çağrısı BufferedSource yineleyici tarafından döndürülen öğelere boş dizeyle katıldı (bunun nedeni, argüman olmadan mkString adını vermenizdir). Bu, koleksiyondaki tüm dizeleri (BufferedSource yineleyici tarafından elde edilen) birleştirerek sonuçlanır.

Diğer taraftan, toString'i çağırmak gerçekten mantıklı gelmiyor, ne elde edeceğiniz (bir hata almazsanız) BufferedSource yineleyicisinin dize olarak temsilidir; Bu sadece yineleyicinin boş olmadığını söyler.

+0

"Bir nesnenin dize temsili", nesnel bir yolun, her bir nesnenin temsil edildiği yerde olduğu gibi biraz ses çıkarır. Aslında, java.lang.Object dosyasında tanımlanan ".toString()" yöntemi, sınıf veya ara bir üst öğenin üzerine yazmaması durumunda kullanılır. Aksine, mkString sadece Scala'nın birkaç koleksiyon sınıfında tanımlanmıştır. Ve soruya işaret ettiği gibi, aynı sonucu üretmezler. mkString, veri için yararlı bir şekilde tanımlanmıştır: scala.io.BufferedSource = boş olmayan yineleyici, toString() o kadar değil. Simon Peyton-Jones tarzı tanıtım için –

1

Farklı sınıflardaki farklı yöntemler bunlar. Bu durumda, mkString, GenTraversableOnce özelliğinde bir yöntemdir. toString, Herhangi bir (ve genellikle çok fazla geçersiz kılındı) olarak tanımlanır.

Bunu bulmak için en kolay yol (veya en azından kullandığım şekilde), belgeleri http://www.scala-lang.org/api/current/index.html adresinde kullanmaktır. senin değişkenin türü ile başlayın:

val data = io.Source.fromFile("file.txt") 

Çeşidi

scala.io.BufferedSource 

BufferedSource için dokümana git ve mkString için bak olduğunu. mkString için doc (aşağı sola üzerinde ok isabet) olarak bunu

Definition Classes TraversableOnce → GenTraversableOnce 

geldiğini göreceksiniz Ve toString ile aynı şeyi yapın.

30

Türlerine bakalım mı?

scala> import scala.io._ 
import scala.io._ 

scala> val foo = Source.fromFile("foo.txt") 
foo: scala.io.BufferedSource = non-empty iterator 

scala> 

Şimdi, dosyayı foo.txt okudum değişken Yineleyicinin. Üzerinde toString() çağrı gerçekleştirirseniz, oluşturduğunuz yineleyicinin Dize gösterimi yerine dosyanın içeriğini döndürmez.OTOH, mkString() yineleyiciyi okur (diğer bir deyişle, üzerinde yineler) ve ondan okunan değerlere bağlı olarak uzun bir String oluşturur. Daha fazla bilgi için

, bu konsol oturumuna bakmak:

scala> foo.toString 
res4: java.lang.String = non-empty iterator 

scala> res4.foreach(print) 
non-empty iterator 
scala> foo.mkString 
res6: String = 
"foo 
bar 
baz 
quux 
dooo 
" 

scala> 
+4

+1 :) – adamnfish

0

Sorunun ne yaptığını Kaynak sınıfı anlamak olduğunu düşünüyorum. Kodunuzdan kaynak FileFromFile bir dosyanın içeriğini gerçekten ne yaptığını bir dosyanın başlangıcını işaret etmek için aldığını beklediğiniz gibi görünüyor.

Bu, bir kaynakla "bağlantı" açmanız gereken (bu durumda dosya sisteminizle bir bağlantı) açmak zorunda olduğunuz G/Ç işlemleriyle çalışırken tipiktir, birkaç kez oku/yaz ve ardından bu "bağlantıyı" kapatın. Örneğinizde bir dosyaya bir bağlantı açarsınız ve sonuna kadar ulaşana kadar dosyanın içeriğini satır başına satır okumalısınız. Bilgiyi okuduğunuzda, belleğe bilgi yüklediğinizi düşünün. Bu yüzden, tüm dosyaları, senaryoların çoğunda belleğe yüklemek iyi bir fikir değildir (mkString bunu yapar).

Diğer taraftan mkString, bir koleksiyonun tüm öğeleri üzerinde yineleme yapmak için yapılır, bu durumda, dosyanın okunması ve bir Array [String] belleğe yüklenmesidir. Dikkatli olun çünkü dosya büyükse kodunuz başarısız olacaktır, normalde G/Ç ile çalışırken, bazı içeriği okumak için bir arabellek kullanmanız, sonra içeriği kaydedip kaydetmeniz ve daha fazla içerik yüklemeniz (aynı tamponda), sorunlardan kaçınmanız gerekir. hafıza ile. > Ayrıştırma - - 5 satırları okurken Örneğin> ayrıştırılan satırları kaydetmek -> okumak önümüzdeki 5 satır -> vb

Ayrıca "toString" sana bir şey alır anlayabiliyorum

... sadece sen "anlatır satırları okuyabilir, dosya boş değil ".

İlgili konular