2014-05-03 14 views
5

Can all usages of forSome be replaced by an equivalent usage of _?, sorunun cevabını gördüm, ancak "forSome" yerine "_" nin kullanılamayacağı gerçek durumun ne olduğunu anlamadım.Gerçek örnek "ForSome" un tüm kullanımları eşdeğer kullanımı ile değiştirilebiliyor mu?

Varoluşçu tipleri dilin tam olarak desteklenen parçasıdır, ancak Scala Java türlerini erişirken pratikte bunlar öncelikli olarak: Bunu Programming in Scala kitapta okudum.

object Main { 
    def main(args: Array[String]): Unit = { 
    type Test = java.util.Collection[T] forSome { type T } 
    val contents: Test = (new Wild).contents 

    type Test2 = java.util.Collection[_] 
    val contents2: Test2 = (new Wild).contents 

    // foo((new Wild).contents2) // won't compile 

    foo1((new Wild).contents2) 
    foo1((new Wild).contents3) 

    foo2((new Wild).contents3) 
    } 

    def foo(xs: java.util.Map[T, T] forSome { type T }) {} 
    def foo1(xs: java.util.Map[_, _]) {} 
    def foo2(xs: java.util.Map[_, _ <: java.lang.Number]) {} 
} 

Java: Ben "ile "forSome" yerine başardı Her durumda

public class Wild { 
    public Collection<?> contents() { 
     return null; 
    } 
    public Map<?, ?> contents2() { 
     return null; 
    } 
    public Map<?, ? extends Number> contents3() { 
     return null; 
    } 
} 

_ Ben Scala projesini oluşturduktan ve buna Java biri başvurulan:

Scala ". Peki "forSome" gerekli olan gerçek durumlar nelerdir? Lütfen basit bir çalışma örneği sağlayın.

cevap

10

İşte oldukça basit bir örnek. Sadece listeye aynı içerdiği tip setleri depolamak mümkün değilim

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 

Not. Ben yapamam. Bu:

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set("a", "b", "c")) 

listOfSets tipi forSome olmadan inexpressable olduğunu. Nitekim

val listOfSets2: List[Set[_]] 

val listOfSets2: List[Set[T] forSome { type T }] 

eşdeğerdir ve bu liste farklı türleri kümeler içeren anlamına gelir, bu nedenle bu işin hem:

val listOfSets2: List[Set[_]] = List(Set(1, 2, 3), Set(4, 5, 6)) 
val listOfSets2: List[Set[_]] = List(Set(1, 2, 3), Set("a", "b", "c")) 

Bu ilginç Scala yorumlayıcısını scala -feature olarak çalıştırırsanız ve bu yanıtın ilk satırını çalıştırmayı denerseniz, tam olarak bir uyarı alırsınız. wildcard ile varoluşsal Çeşidi nexpressability:

scala> val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 
<console>:7: warning: the existential type List[Set[T]] forSome { type T }, which cannot be expressed by wildcards, should be enabled 
by making the implicit value scala.language.existentials visible. 
This can be achieved by adding the import clause 'import scala.language.existentials' 
or by setting the compiler option -language:existentials. 
See the Scala docs for value scala.language.existentials for a discussion 
why the feature should be explicitly enabled. 
     val listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 
            ^
listOfSets: List[Set[T]] forSome { type T } = List(Set(1, 2, 3), Set(4, 5, 6)) 

başka bir örnek yoktur. Bir sınıfı bir sınıfın tek bir örneğine eşlemek istediğinizi varsayalım. Bu, bu tip ifade edilebilir: Doğru türünü yazamıyor

val classInstanceMap: Map[Class[T], T] forSome { type T } 

forSome olmadan - anahtarları ve değerleri türleri "ilişki" için başka bir yolu yoktur.Örneğin, joker karakterler ile bu tip:

val invalidClassInstanceMap: Map[Class[_], _] 

hiç ilgili olmayan

val invalidClassInstanceMap: Map[Class[K] forSome { type K }, V] forSome { type V } 
İşte

K ve V eşdeğerdir, dahası, tuşlar keyfi T için Class[T] keyfi örneklerini olabilir, ancak tüm edebilirsiniz değerler aynı türde olmalıdır.

+0

Teşekkür ederiz! Şimdilik açık. – user4298319

İlgili konular