Una de las nuevas características de Scala 2.8 son los límites de contexto. ¿Qué es un contexto limitado y dónde es útil?
Por supuesto, busqué primero (y encontré, por ejemplo, esto ) pero no pude encontrar ninguna información realmente clara y detallada.
scala
scala-2.8
context-bound
Jesper
fuente
fuente
Respuestas:
¿Encontraste este artículo ? Cubre la nueva función vinculada al contexto, dentro del contexto de las mejoras de la matriz.
Generalmente, un parámetro de tipo con un límite de contexto tiene la forma
[T: Bound]
; se expande a un parámetro de tipo planoT
junto con un parámetro implícito de tipoBound[T]
.Considere el método
tabulate
que forma una matriz a partir de los resultados de aplicar una función f dada en un rango de números desde 0 hasta una longitud determinada. Hasta Scala 2.7, el tabulado se podría escribir de la siguiente manera:En Scala 2.8 esto ya no es posible, porque la información en tiempo de ejecución es necesaria para crear la representación correcta de
Array[T]
. Es necesario proporcionar esta información pasando unClassManifest[T]
en el método como un parámetro implícito:Como forma abreviada, se puede usar un enlace de contexto en el parámetro de tipo
T
, dando:fuente
La respuesta de Robert cubre los detalles técnicos de Context Bounds. Te daré mi interpretación de su significado.
En Scala, un View Bound (
A <% B
) captura el concepto de 'se puede ver como' (mientras que un límite superior<:
captura el concepto de 'es un'). Un límite de contexto (A : C
) dice 'tiene un' sobre un tipo. Puede leer los ejemplos sobre manifiestos como "T
tiene unManifest
". El ejemplo al que vinculó acerca deOrdered
vsOrdering
ilustra la diferencia. Un métododice que el parámetro puede verse como un
Ordered
. Comparar conque dice que el parámetro tiene asociado
Ordering
.En términos de uso, tomó un tiempo establecer las convenciones, pero se prefieren los límites de contexto a los límites de vista (los límites de vista ahora están en desuso ). Una sugerencia es que se prefiere un enlace de contexto cuando se necesita transferir una definición implícita de un alcance a otro sin necesidad de hacer referencia a él directamente (este es ciertamente el caso de los
ClassManifest
utilizados para crear una matriz).Otra forma de pensar sobre los límites de la vista y los límites del contexto es que la primera transfiere conversiones implícitas desde el alcance del llamador. El segundo transfiere objetos implícitos del alcance del llamador.
fuente
has a
Tiene más sentido para mí](Esta es una nota entre paréntesis. Lea y comprenda primero las otras respuestas).
Los límites de contexto en realidad generalizan los límites de vista.
Entonces, dado este código expresado con un View Bound:
Esto también podría expresarse con un Context Bound, con la ayuda de un alias de tipo que represente funciones de un tipo
F
a otroT
.Un límite de contexto debe usarse con un constructor de tipo de tipo
* => *
. Sin embargo, el constructorFunction1
de tipos es de su tipo(*, *) => *
. El uso del alias de tipo aplica parcialmente el segundo parámetro de tipo con el tipoString
, produciendo un constructor de tipo del tipo correcto para su uso como un límite de contexto.Existe una propuesta que le permite expresar directamente tipos aplicados parcialmente en Scala, sin el uso del alias de tipo dentro de un rasgo. Entonces podrías escribir:
fuente
From
de tipo del tipoTo[String]
. No proporcionamos un argumento de tipo aFrom
, por lo que nos referimos al constructor de tipos, no a un tipo. Este constructor de tipos es del tipo adecuado para ser utilizado como un límite de contexto -* -> *
. Esto limita el parámetro de tipoT
al requerir un parámetro implícito de tipoTo[String]#From[T]
. Expanda los alias de tipo y listo, se quedaFunction1[String, T]
.Esta es otra nota entre paréntesis.
Como señaló Ben , un límite de contexto representa una restricción "tiene-a" entre un parámetro de tipo y una clase de tipo. Dicho de otra manera, representa una restricción de que existe un valor implícito de una clase de tipo particular.
Cuando se utiliza un límite de contexto, a menudo es necesario resaltar ese valor implícito. Por ejemplo, dada la restricción
T : Ordering
, a menudo se necesitará la instancia deOrdering[T]
que satisfaga la restricción. Como se demuestra aquí , es posible acceder al valor implícito mediante elimplicitly
método o un método un poco más útilcontext
:o
fuente