Pregunta

De una manera sencilla, lo que dependen del contexto y ver los límites y ¿cuál es la diferencia entre ellos?

Algunos ejemplos fáciles de seguir sería grande también!

¿Fue útil?

Solución

pensé que esto fue preguntado ya, pero, si es así, la pregunta no es evidente en la "relacionada" bar. Por lo tanto, aquí está:

¿Qué es una vista en Bound?

A Ver obligados era un mecanismo introducido en Scala para permitir el uso de algún tipo A como si se tratara de algún tipo B. La sintaxis típica es la siguiente:

def f[A <% B](a: A) = a.bMethod

En otras palabras, A debe tener una conversión implícita a B disponible, por lo que uno puede llamar a métodos B en un objeto de tipo A. El uso común de la mayoría de vista los límites de la biblioteca estándar (antes 2.8.0 Scala, de todos modos), es con Ordered, como esto:

def f[A <% Ordered[A]](a: A, b: A) = if (a < b) a else b

Debido a que se puede convertir en un A Ordered[A], y porque Ordered[A] define el método <(other: A): Boolean, puedo usar la a < b expresión.

Por favor, tenga en cuenta que vista de los límites están en desuso , usted debe evitar.

lo que habrá un contexto?

fuera de contexto se introdujeron en Scala 2.8.0, y se utilizan típicamente con el llamado patrón de clase tipo , un patrón de código que emula la funcionalidad proporcionada por las clases de tipos de Haskell, aunque en una más prolija manera.

Mientras una vista unido puede utilizarse con tipos simples (por ejemplo, A <% String), un contexto ligado requiere un tipo parametrizado , como Ordered[A] anteriormente, pero a diferencia de String.

Un contexto unido describe un implícito valor , en lugar de vista de obligado implícita conversión . Se utiliza para declarar que por algún tipo A, hay un valor implícito de B[A] tipo. La sintaxis es la siguiente:

def f[A : B](a: A) = g(a) // where g requires an implicit value of type B[A]

Esto es más confusa que la vista obligada, ya que no está claro de inmediato cómo usarlo. El ejemplo común de uso en Scala es la siguiente:

def f[A : ClassManifest](n: Int) = new Array[A](n)

una inicialización Array en un tipo parametrizado requiere un ClassManifest para estar disponible, por razones arcanas relacionadas con el tipo de borrado y la naturaleza no borrado de arrays.

Otro ejemplo muy común en la biblioteca es un poco más complejo:

def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b)

Aquí, implicitly se utiliza para retrive el valor implícito que queremos, uno de tipo Ordering[A], que clase define el método compare(a: A, b: A): Int.

Vamos a ver otra forma de hacer esto más adelante.

¿Cómo se Ver límites y contexto límites implementados?

No debe sorprender que ambos límites vista agigantados contexto se implementan con parámetros implícitos, dada su definición. En realidad, la sintaxis he mostrado son azúcares sintácticas para lo que realmente sucede. Vea a continuación la forma en que de-azúcar:

def f[A <% B](a: A) = a.bMethod
def f[A](a: A)(implicit ev: A => B) = a.bMethod

def g[A : B](a: A) = h(a)
def g[A](a: A)(implicit ev: B[A]) = h(a)

Así que, naturalmente, se puede escribir en todo su sintaxis, que es especialmente útil para los límites de contexto:

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = ord.compare(a, b)

¿Cuáles son los límites Ver utiliza?

Ver límites se utilizan sobre todo para tomar ventaja de la chulo mi biblioteca patrón, a través del cual se "añade" métodos a una clase existente, en situaciones en las que desee devolver el tipo original de alguna manera. Si no es necesario volver a ese tipo de ninguna manera, entonces no es necesario un punto de vista determinado.

El ejemplo clásico de vista de uso límite está manejando Ordered. Tenga en cuenta que no se Int Ordered, por ejemplo, aunque no hay una conversión implícita. El ejemplo dado previamente necesidades una vista unida porque devuelve el tipo no convertida:

def f[A <% Ordered[A]](a: A, b: A): A = if (a < b) a else b

Este ejemplo no funcionará sin visión límites. Sin embargo, si tuviera que volver otro tipo, entonces yo no necesito un punto de vista más obligado:

def f[A](a: Ordered[A], b: A): Boolean = a < b

La conversión aquí (si es necesario) ocurre antes de pasar el parámetro a f, sO f no necesita saber acerca de ella.

Además Ordered, el uso más común de la biblioteca está manejando String y Array, que son clases Java, como si fueran colecciones Scala. Por ejemplo:

def f[CC <% Traversable[_]](a: CC, b: CC): CC = if (a.size < b.size) a else b

Si uno trató de hacer esto sin límites vista, el tipo de retorno de un String sería un WrappedString (Scala 2,8), y lo mismo para Array.

Lo mismo ocurre incluso si el tipo sólo se utiliza como un parámetro de tipo del tipo de retorno:

def f[A <% Ordered[A]](xs: A*): Seq[A] = xs.toSeq.sorted

¿Qué se utilizan límites contexto para?

límites de contexto se utilizan principalmente en lo que se conoce como clase de tipos patrón , como una referencia a las clases de tipos de Haskell. Básicamente, este patrón implementa una alternativa a la herencia al hacer funcionalidad disponible a través de una especie de adapter implícita.

El ejemplo clásico es Ordering de Scala 2,8, que sustituyó Ordered largo de la biblioteca de Scala. El uso es:

def f[A : Ordering](a: A, b: A) = if (implicitly[Ordering[A]].lt(a, b)) a else b

A pesar de que se suele ver que escribe así:

def f[A](a: A, b: A)(implicit ord: Ordering[A]) = {
    import ord.mkOrderingOps
    if (a < b) a else b
}

que se aprovechan de algunas conversiones implícitas dentro Ordering que permiten el estilo tradicional del operador. Otro ejemplo en Scala 2.8 es la Numeric:

def f[A : Numeric](a: A, b: A) = implicitly[Numeric[A]].plus(a, b)

Un ejemplo más complejo es el nuevo uso de la colección de CanBuildFrom, pero ya hay una larga respuesta sobre eso, así que voy a evitar aquí. Y, como se mencionó antes, está el uso de ClassManifest, que se requiere para iniciar nuevas matrices sin tipos concretos.

El contexto ligado con el patrón de clase de tipos es mucho más probable que se utilicen por sus propias clases, ya que permiten la separación de las preocupaciones, mientras que Vista límites se pueden evitar en su propio código de buen diseño (que se utiliza sobre todo para moverse algún otro diseño).

A pesar de que ha sido posible por un largo tiempo, el uso de los límites de contexto ha tenido tanto éxito en 2010, y ahora se encuentran en algún grado en la mayor parte de la mayoría de las bibliotecas y los marcos importantes de Scala. El ejemplo más extremo de su uso, sin embargo, es la biblioteca Scalaz, que aporta una gran cantidad de poder de Haskell a Scala. Recomiendo leer sobre los patrones de clase de tipos para obtener un mayor conocimiento que todas las formas en que se puede utilizar.

Editar

preguntas relacionadas de interés:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top