Jedną z nowych funkcji Scali 2.8 są ograniczenia kontekstowe. Co to jest kontekst i gdzie jest przydatne?
Oczywiście najpierw szukałem (i znalazłem na przykład to ), ale nie mogłem znaleźć żadnych naprawdę jasnych i szczegółowych informacji.
scala
scala-2.8
context-bound
Jesper
źródło
źródło
Odpowiedzi:
Znalazłeś ten artykuł ? Obejmuje nową funkcję związaną z kontekstem w kontekście ulepszeń tablicy.
Ogólnie parametr typu z powiązanym kontekstem ma postać
[T: Bound]
; jest rozszerzany do zwykłego parametru typuT
wraz z niejawnym parametrem typuBound[T]
.Rozważ metodę,
tabulate
która tworzy tablicę z wyników zastosowania danej funkcji f do zakresu liczb od 0 do określonej długości. Do wersji Scala 2.7 tabelę można zapisać w następujący sposób:W Scali 2.8 nie jest to już możliwe, ponieważ informacje o środowisku wykonawczym są niezbędne do stworzenia właściwej reprezentacji
Array[T]
. Tę informację trzeba podać, przekazującClassManifest[T]
do metody jako niejawny parametr:W skrócie, w parametrze typu można użyć ograniczenia kontekstu
T
, dając:źródło
Odpowiedź Roberta obejmuje techniczne szczegóły granic kontekstu. Podam ci moją interpretację ich znaczenia.
W Scali a View Bound (
A <% B
) przechwytuje pojęcie „może być postrzegane jako” (podczas gdy górna granica<:
obejmuje pojęcie „jest”). Kontekst powiązany (A : C
) mówi „ma” o typie. Możesz przeczytać przykłady dotyczące manifestów jako „T
maManifest
”. Przykład, do którego prowadzi link aboutOrdered
vs,Ordering
ilustruje różnicę. Metodamówi, że parametr można postrzegać jako plik
Ordered
. Porównać zco mówi, że parametr ma skojarzony
Ordering
.Pod względem użytkowania ustalenie konwencji zajęło trochę czasu, ale granice kontekstu są preferowane zamiast granic widoku ( granice widoku są teraz przestarzałe ). Jedną z sugestii jest to, że ograniczenie kontekstu jest preferowane, gdy trzeba przenieść niejawną definicję z jednego zakresu do innego bez konieczności bezpośredniego odwoływania się do niej (z pewnością dotyczy to
ClassManifest
użycia do tworzenia tablicy).Innym sposobem myślenia o granicach widoku i granicach kontekstu jest to, że pierwsza przenosi niejawne konwersje z zakresu wywołującego. Drugi przesyła niejawne obiekty z zakresu wywołującego.
źródło
has a
dla mnie więcej sensu](To jest uwaga w nawiasach. Najpierw przeczytaj i zrozum pozostałe odpowiedzi).
Granice kontekstu w rzeczywistości uogólniają granice widoku.
Tak więc, biorąc pod uwagę ten kod wyrażony za pomocą ograniczenia widoku:
Można to również wyrazić za pomocą Context Bound, za pomocą aliasu typu reprezentującego funkcje od typu
F
do typuT
.Powiązany kontekst musi być używany z konstruktorem typu
* => *
. Jednak konstruktor typuFunction1
jest miły(*, *) => *
. Użycie aliasu typu częściowo powoduje zastosowanie drugiego parametru typu z typemString
, dając konstruktor typu poprawnego rodzaju do użycia jako powiązany z kontekstem.Istnieje propozycja umożliwiająca bezpośrednie wyrażanie częściowo zastosowanych typów w Scali, bez użycia aliasu typu wewnątrz cechy. Możesz wtedy napisać:
źródło
From
typuTo[String]
. NieFrom
podajemy argumentu typu , więc odwołujemy się do konstruktora typu, a nie do typu. Ten konstruktor typu jest odpowiedniego rodzaju i może być używany jako powiązany z kontekstem -* -> *
. To wiąże parametr typuT
, wymagając niejawnego parametru typuTo[String]#From[T]
. Rozwiń aliasy typów i voila, zostajesz zFunction1[String, T]
.To kolejna uwaga w nawiasach.
Jak zauważył Ben , powiązanie kontekstu reprezentuje ograniczenie typu „ma” między parametrem typu a klasą typu. Innymi słowy, reprezentuje ograniczenie, że istnieje niejawna wartość określonej klasy typu.
Korzystając z kontekstu, często trzeba ujawnić tę niejawną wartość. Na przykład, biorąc pod uwagę ograniczenie
T : Ordering
, często będzie potrzebny egzemplarz,Ordering[T]
który spełnia to ograniczenie. Jak pokazano tutaj , możliwy jest dostęp do niejawnej wartości przy użyciuimplicitly
metody lub nieco bardziej pomocnejcontext
metody:lub
źródło