2011-05-25 16 views
8

Scala Newb vs ... BenScala Diziler Vektörler

object myApp extends App { 
    println("Echo" + (args mkString " ")) 
} 

"args" kafam karışık tip Dizisi [dize], fakat scaladoc içinde, Dizi böyle bir yöntem vardır. mkString, Vector için bir yöntemdir, ancak ikisi arasında herhangi bir miras bağlantısı görmüyorum. Öyleyse mkString yöntemini neden hatalar üzerinde kullanabiliriz?

cevap

16

Ben bir scala uzmanı değilim (ondan çok uzak!) Ama bence yanıt örtülü dönüşümler (bkz. scala.Predef) ve WrappedArray.scala. Özellikle

, PREDEF aşağıdaki örtülü dönüşüm vardır:

implicit def genericWrapArray [T] (xs: Array[T]): WrappedArray[T] 

ve WrappedArray bir mkString yöntemi vardır. Scala, Dizi’da mkString yöntemini bulamadığında, bu tür bir türe örtük bir dönüşüm arar. $ .Html

http://www.scala-lang.org/api/current/scala/collection/mutable/WrappedArray.html

+2

Teşekkürler, örtük dönüşümler yönelmedim. WrappedArray ve Vector, her ikisi de paylaştıkları TraversableOnce özelliğinden mkString yöntemini alır. Eğer scaladoc bir sınıfın tanımında size örtülü kusurların var olduğunu söylemiş olsaydı faydalı olabilir mi? –

12

Kevin'in yanıta genişletilmesi ve örtük dönüştürme var olanı söylemek scaladoc için muhtemelen değil açıklarken

http://www.scala-lang.org/api/current/scala/Predef: Örtülü dönüşüm, yalnızca devreye girer zaman kod olmaz Aksi halde derleyin.

Derleme sırasında etkinleştirilen tür hataları için bir hata düzeltme mekanizması olarak görebilirsiniz. Bu durumda, Array[String], mkString yöntemine sahip değildir. Bu kod, Array[T]'da mevcut olmadığı için derlenmez. Ancak derleyiciden vazgeçmeden önce kapsamda örtük bir dönüşüm arayacak.

Predef, kapsam dahilinde ve burada geçerli olan bir dizi örtülü dönüşüm getiriyor.

Hangi örtük dönüşümün uygulanabileceğini bulmak -Xprint:typer bayrağını kullanarak derleme yapabilir. Bu durumda baskı olacaktır:

$ scalac -d classes -Xprint:typer A.scala 
[[syntax trees at end of typer]]// Scala source: A.scala 
package <empty> { 
    final object myApp extends java.lang.Object with App with ScalaObject { 
    def this(): object myApp = { 
     myApp.super.this(); 
    () 
    }; 
    scala.this.Predef.println("Echo ".+(scala.this.Predef.refArrayOps[String](myApp.this.args).mkString(" "))) 
    } 
} 

Yani Predef.refArrayOps örtülü dönüşüm kullanılan aslında olduğunu görebilirsiniz. Dizinizi mkString method olan ArrayOps[String]'a dönüştürür.

Dolayısıyla, Array10 neden örtülü dönüşümün uygulanabileceğini size söyleyemediğini anlayabilirsiniz. Her şey olabilirdi. Aslında tamamen böyle bir yöntem olmadığı gerçeğine dayanmaktadır. Sadece derleyici, kodu temel alarak ne kadar örtük olduğunu bilir.

Hatta kendi örtük dönüştürme tanımlayabilirsiniz: aşağıdaki etkiye sahip olacaktır

object myApp extends App { 
    implicit def myImplicit(arr:Array[String]) = new { 
    def mkString(s:String) = arr.length + s 
    } 
    println("Echo " + (args mkString(" "))) 
} 

:

Açıkçası
$ scala -cp classes myApp a b c 
Echo 3 

scaladoc göstermek mümkün olmayacaktır. Eclipse Scala fişinin sizi F3 tuşuna basarak mkString uygulamasına getirebileceğini unutmayın (TraversableOnce ile sonuçlanacaktır).

+0

Detaylı açıklama için teşekkürler :) –

2

Ancak Scaladoc en azından Predef'in (her zaman kapsam içinde olduğu için özel olan) Array'dan dolaylı bir dönüşüme sahip olduğunu söyleyebilirdi. Bu yararlı olur.