2013-08-28 34 views
6

Scala derleyici, çalışma zamanında herhangi bir potansiyel boş işaretçi dereference olup olmadığını kontrol etmeye çalışan -Xcheck-null vardır.Mark yöntem çağrısı her zaman döndürmez null sonucu döndürür

Benim için Tamam, ama ben logger tanımlamak varsayalım, yani çok fazla yanlış pozitif olsun: getLogger asla null döndürür

private final val LOGGER: Logger = LoggerFactory.getLogger(classOf[GenericRestImpl]) 

yöntemi. Bu bilgiyi derleyiciye nasıl iletebilirim ki şikayet etmeyecek? Ben yeni bir örneğini oluşturduğunuzda

[WARNING] TestImpl.scala:31: warning: potential null pointer dereference: LOGGER.debug 
[WARNING]  LOGGER.debug("Using {} for sort", sortParam) 

Ben NotNull özelliği ile işaretleyebilirsiniz:

return new Foo() with NotNull. 
Tamam

ama ne nesneler diğer yöntemlerle döndü ilgisi? Özellikle 3. parti kütüphaneden geliyorsa? Tüm değişkenlerimi İsteğe bağlı olarak işaretlemekten hoşlanmıyorum çünkü fazla yük ekleyecektir. Ayrıca, örtük dönüşümler yaratmayı sevmiyorum (Notnull olarak işaretlemek istediğim her sınıf için ekstra sınıf gerektirecektir çünkü

Ayrıca Library support for Scala's NotNull trait sorusunu da kontrol ettim, ancak sorunumu çözmemde yardımcı olmadı. bir şey etiketlemek için NotNull kullanabilmesi

+0

Doğru anlamıyorsunuz, NotNull özelliği sadece bir işaretleyicidir. Daha fazlasını yapmaz. – Jatin

cevap

5

Jatin bahseder gibi, NotNull, sadece işaretçi veya etikettir. bunu yapmanın hile bir döküm için baz tipi with NotNull.

böylece gibi bir şey yazabilirsiniz zorlayarak etmektir Bu "notnull".asInstanceOf[String with NotNull]. Hiç boş olmadığından eminseniz güvenli bir dökümdür

Gerçek örnekte

, bu nedenle yazabilirsiniz:

private final val LOGGER: Logger with NotNull = 
    LoggerFactory.getLogger(classOf[GenericRestImpl]).asInstanceOf[Logger with NotNull] 

bu yeni türleri oluşturmak için gerek yoktur ederken, onu çok yapmak zorunda eğer biraz hantal, bazı kullanabilir böylece küçük utils gösterimini netleştirmek/basitleştirmek için:

type NeverNull[T] = T with NotNull 
def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull] 

NeverNullNotNull ve neverNull ile etiketlenmiş her tür T için sadece bir takma asla boş olarak tip A herhangi varolan değeri etiketlemek için biraz sarıcı.

implicit def neverNull[A](a: A): NeverNull[A] = a.asInstanceOf[A with NotNull] 

private final val LOGGER: NeverNull[Logger] = LoggerFactory.getLogger(classOf[GenericRestImpl]) 

Not NeverNull[Logger] hala geçerli: Ne yapıyorsun gerçekten eminseniz

private final val LOGGER: NeverNull[Logger] = neverNull { 
     LoggerFactory.getLogger(classOf[GenericRestImpl]) 
} 

Hatta, bu örtük dönüştürme yapabilir:

Daha sonra olarak kullanabilirsiniz Bir Logger, böylece o sınıfın herhangi bir yöntemini çağırabilir veya Logger parametresi olarak kabul edilen işlevlere iletebilirsiniz.

yapının Bu tür bir kutusuz etiketli tip denilen ve oldukça yararlıdır, diğer uygulamaları ve tartışmayı here ve here mi göreceğiz.

İlgili konular