2016-04-06 4 views
0

Да! Другой из этого вопроса, и да, я уже много читал эти вопросы в stackoverflow и до сих пор не понимаю эту концепцию и ее приложение.Scala Co и контравариантность

Итак, я - новый посетитель Скалы, и, как и многие люди, я до сих пор не получил концепцию контравариантности, я читаю Программу Scala, 2nd Edition и на странице 283 начинает объяснение co и контрвариантность на следующем примере:

дает иерархию:

class CSuper { def msuper() = println("CSuper") } 
class C extends CSuper { def m() = println("C") } 
class CSub extends C { def msub() = println("CSub") } 

то есть функция, и некоторые примеры использования:

var f: C => C = (c: C) => new C 
    f   = (c: CSuper) => new CSub 
    f   = (c: CSuper) => new C 
    f   = (c: C) => new CSub 
    f   = (c: CSub) => new CSuper // COMPILATION ERROR! 

мышления в Java Я знаю, что последнее выражение не будет компилироваться, потому что CSuper является супертипом CSub.

Что я не понимаю, что означает тип, в этом случае функция 1 [-C, + C] является контравариантной в первом параметре?

В книге говорится, что для контрвариации когда where X[String] is a supertype of X[Any], for some type X.

Сотрудничество/контрвариантность просто appliable в подклассах параметризованных типов, я имею в виду, так как мы используем FUNCTION1, дисперсия просто относится к подтипам Function1, не так ли?

И как это работает, и когда мне это нужно/нужно?

+0

«Я уже много читал в этом вопросе в stackoverflow и до сих пор не понимаю ...» - в вашем вопросе о том, что мы могли бы написать, на самом деле нет никакого полезного указания, которое не было бы таким же, как которые вы уже прочитали.вы задали несколько вопросов здесь, все они очень широкие, и все они дублируются. –

+0

@SethTisue, да, я думаю, что вопросы, которые я уже прочитал, имеют знания, которые я ищу, но, как они отвечают, меня не понимает, я надеялся, что кто-то может объяснить по-другому. –

+0

@KennedyOliveira Ищите Принцип замены Лискова. – pedrofurla

ответ

2

если T 'является подклассом T, является ли контейнер T [] рассмотренным подклассом контейнера [T]?

[+T]ковариантный: С [Т '] является подклассом C [T],
[-T]контравариантным: С [Т] является подклассом C [T']

Function1 определяется как trait Function1[-T1, +R], поэтому параметры контравариантны, а тип результата является ковариантным.

Это означает, что функции, какие аргументы являются супертипами аргумента типа данной функции, и которые приводят тип подтипа результирующего типа данной функции является самим подтипом данной функции.

В вашем примере, поскольку вы назначаете различные объявления функций f типа C => C, будет скомпилировано только присвоение действительных подтипов.

А именно, только эти функции заявление являются действительными подтипами C => C:

var f: C => C = (c: C) => new C 
f   = (c: C) => new C 
f   = (c: C) => new CSub 
f   = (c: CSuper) => new C 
f   = (c: CSuper) => new CSub 

Все остальное либо супертип C => C и не может быть отнесен к f или неродственному типу.

Смежные вопросы