2012-02-27 27 views
5

Örneğin, silme sınıfı almak için def a[A:ClassManifest] işlevindeki bildirime erişmem gerekiyor. Predef.implicitly işlevini kullanabilirim ancak bu durumda kodum def a[A](implicit b:ClassManifest[A]) tam formunu kullanmış olduğum sürece olacaktır. Bu örtük argümanlar için uygun üretilmiş isimler var mı? sırasıyla manifest[T], classManifest[T] ve optManifest[T]:"Kapalı" olarak nasıl örtülü olarak erişebilirim, yani [A: B] veya [A <% B] hatalarını nasıl çözebilirim?

+1

Her zaman daha küçük bir ada sahip bir yöntem bildirebilirsiniz, ancak Scalac tarafından oluşturulan sihir adlarına bağlı olarak _not_ olmalıdır. –

cevap

5

Manifest s için yapacak Predef içinde önceden tanımlanmış üç yöntemleri, ClassManifest ler ve OptManifest ler vardır. Aynı modele göre diğer tür sınıflar için kendi "gizli alıcıları" yazabilirsiniz. Yani burada

def manifest[T](implicit m: Manifest[T]) = m 

Kendi yazabilirsiniz nasıl: Burada örneğin manifest[T] içindir kurtarmaya

trait UsefulTypeclass[A] { 
    def info = 42 // sample method 
} 

// the “implicit getter” 
def usefulTypeclass[A](implicit tc: UsefulTypeclass[A]) = tc 

// a method that uses the implicit getter 
def foo[A: UsefulTypeclass] = 
    usefulTypeclass[A].info 
+2

Düzgün bir hile olarak: örtülü alıcıyı "uygula" olarak adlandırır ve UsefulTypeclass'ın eşlik eden nesnesine eklerseniz, "UsefulTypeclass [T]" öğesinin T için tipeclass örneğini temsil eden bir değer olarak kullanabilirsiniz. typeclass kendisi. –

+0

@RM Güzel numara. O zaman UsefulTypeclass [T]() '(extra'() ') ile olmalı. –

+0

Aslında parense ihtiyacı yok. Eğer varsa (biçimlendirme eksikliğinden dolayı) nesneyi TC {def geçerlidir [T] (örtülü x: TC [T]) = x} "uygula" tanımlandığından dolayı sadece "TC [SomeClass]" ile tam anlamıyla çağırabilirsiniz. örtük bir parametre listesiyle parametresiz bir yöntem olarak ve [SomeClass] bunu yalnızca TC nesnesine yapılan bir referanstan ayırır. TC.apply [SomeClass] (theImplicitValue) –

0

Scalap!

Bu kodu aldı:

object TestThing extends App { 
    def one { println("one") } 
    def two[T] { println("two") } 
    def three[T : Manifest] { println("three") } 
    def four[T: Manifest, U : Manifest] { println("four") } 
} 

ve Scalap aracılığıyla koştu.

object TestThing extends java.lang.Object with scala.App with scala.ScalaObject { 
    def this() = { /* compiled code */ } 
    def one : scala.Unit = { /* compiled code */ } 
    def two[T] : scala.Unit = { /* compiled code */ } 
    def three[T](implicit evidence$1 : scala.Predef.Manifest[T]) : scala.Unit = { /* compiled code */ } 
    def four[T, U](implicit evidence$2 : scala.Predef.Manifest[T], evidence$3 : scala.Predef.Manifest[U]) : scala.Unit = { /* compiled code */ } 
} 

Gördüğünüz gibi, ilk örtük Manifest evidence$1 denir: Burada ne var yani. İkinci ve üçüncü - farklı bir kapsamda olsa!evidence$2 ve evidence$3 olarak adlandırılır. Yani ... bu, Manifesto'lara referans yapıyorsunuz. Bununla birlikte, buna rağmen, sınıfta daha yüksek olan bir Manifest'in kaldırılmasının, dosyada daha aşağıda bulunan bir Manifest'in adını değiştireceğine biraz korkutucu geliyor gibi görünmektedir. Benzer şekilde, IntelliJ Scala eklentisinin sözdizimi vurgulamasının, four() kapsamındaki Manifest değişkenlerinin evidence$1 ve evidence$2 olduğunu düşünmesine de yardımcı olmadığı ve evidence$3'un geçerli bir değişken olduğunu düşünmüyor (ve evidence$1 değil). Genel olarak, bu tür şeyler örtülü Manifest değişkenleri ile oynamaya dair uyarı işaretleri olarak düşünülmelidir?

+2

Kesinlikle bu isimler bir iç uygulama detayı olmalı ve güvenilmemelidir! – Ben

+0

@Ben Benden hiçbir muhalefet alamayacaksınız. – Destin

+1

Bu yüzden 'implicitly' kullanmanızın nedeni budur… kodunuzda '$ 1' vb. Kullanmaya çalışmanız derlenmez. –

İlgili konular