2012-10-07 20 views
17

bazı yöntemler örtülü bir parametre alarak bir sınıf tanımlamak çalışıyorum: Başka bir sınıftan bu sınıfı kullanmaknasıl sınıf düzeyinde örtülü parametreler için varsayılan değer sağlamak üzere

object Greetings { 
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

implicit val greetings = "hello"    //> greetings : java.lang.String = hello 
Greetings.say("loic")       //> res0: String = hello loic 
Greetings.say("loic")("hi")      //> res1: String = hi loic 

Sorunum, yalnızca Greetings nesnesinin dışındaki örtük değeri tanımladığımda çalışır. API'm (Scala toplama API'sı gibi) kullanımını kolaylaştırmak için sınıfımın içinde varsayılan bir değer olan örtülü parametreler içeren yöntemler sağlamak istiyorum.

yüzden bunu yapmak istiyorum ama (örtük değer bulunamadı) çalışmıyor:

object Greetings { 
    implicit val greetings = "hello"  
    def say(name: String)(implicit greetings: String): String = greetings + " " +name 
} 

ve sonra

Greetings.say("loic")       
Greetings.say("loic")("hi") 

ben (implicit greetings: String = "hello") ile varsayılan bir değer tanımlayabilirsiniz biliyorum ama Birçok yöntem varsa tekrarlamayı önlemek için sınıf düzeyinde yapmak istiyorum.

Sanırım bir şey kaçırıyordum, çünküsınıfının içinde CanBuildFrom tanımlandığını gördüm. Bunun gibi

class Greetings(implicit val greetings: String = "hello") { 
    def say(name: String): String = greetings + " " + name 
} 

Ben bir varsayılan değere sahip ve ben istersem geçersiz kılabilirsiniz:

cevap

6

Ben geçici bir çözüm buldum

new Greetings().say("loic")      //> res0: String = hello loic 

implicit val greetings = "hi"     //> greetings : java.lang.String = hi 
new Greetings().say("loic")      //> res1: String = hi loic 

new Greetings()("coucou").say("loic")   //> res2: String = coucou loic 

Not: new Greetings()("coucou") çünkü, değil new Greetings("coucou") çalışıyor bir sözdizimi strangeness açıkladı here.

+0

Değil tuhaf, örtük sadece normal parametreler ikinci eklenecektir beri. Normalde sınıfınız 'Sınıf Greetings() (örtük val ...) ' – thatsIch

24

Böyle bir genel türünü örtülü olarak String olarak kullanmak kötü bir fikirdir. Ana nedeni, dolaylı aramanın yalnızca türün temelini oluşturmasıdır, bu yüzden başka biri String'in başka bir örtülü değerini tanımlarsa ne olur? Bir çatışma ile sonuçlanabilir. Bu yüzden kendi amacınız için kendi amacınızı tanımlamanız gerekir (String'in etrafındaki basit bir sarıcı). Diğer bir sebep ise, örtülü değerler ararken, derleyicinin (diğer yerler arasında) örtülü değer türünün tamamlayıcı nesnesine (varsa) bakmasıdır. Tamamlayıcı nesne, varsayılan bir örtük değer (sizin durumunuzda olduğu gibi) koymak için doğal yer olduğu için, ne kadar kullanışlı olduğunu kolayca görebilirsiniz. Ancak, örtük değer, sahip olmadığınız bir türse (örneğin, String), bunun için bir tamamlayıcı nesne yazamazsınız, kendi sarmalayıcı türünüzle birlikte bir sorun yoktur. Burada

Tamam, yeterince laf kalabalığı, bunu nasıl geçerli:

case class Greetings(value: String) { 
    override def toString = value 
} 
object Greetings { 
    // this implicit is just so that we don't have to manually wrap 
    // the string when explicitly passing a Greetings instance 
    implicit def stringToGreetings(value: String) = Greetings(value) 

    // default implicit Greetings value 
    implicit val greetings: Greetings ="hello" 

    def say(name: String)(implicit greetings: Greetings): String = greetings + " " +name 
} 
Greetings.say("loic")       
Greetings.say("loic")("hi") 
+0

gibi görünecektir. Tamam, anladım, çok teşekkürler :) – Loic

İlgili konular