He echado un vistazo a la lista de encuestas realizadas en scala-lang.org y noté una pregunta curiosa: " ¿Puedes nombrar todos los usos de" _ "? ". ¿Puedes? En caso afirmativo, hazlo aquí. Se aprecian ejemplos explicativos.
540
He echado un vistazo a la lista de encuestas realizadas en scala-lang.org y noté una pregunta curiosa: " ¿Puedes nombrar todos los usos de" _ "? ". ¿Puedes? En caso afirmativo, hazlo aquí. Se aprecian ejemplos explicativos.
Respuestas:
Los que puedo pensar son
Tipos existenciales
Parámetros de tipo kinded más altos
Variables ignoradas
Parámetros ignorados
Nombres ignorados de tipos propios
Patrones comodín
Patrones comodín en interpolaciones
Comodín de secuencia en patrones
Importaciones de comodines
Ocultar importaciones
Unir cartas a operadores
Operadores de Asignación
Sintaxis de marcador de posición
Valores del método
Convertir parámetros de llamada por nombre en funciones
Inicializador predeterminado
¡Puede haber otros que he olvidado!
Ejemplo que muestra por qué
foo(_)
yfoo _
son diferentes:Este ejemplo proviene de 0__ :
En el primer caso,
process _
representa un método; Scala toma el método polimórfico e intenta hacerlo monomórfico al completar el parámetro de tipo, pero se da cuenta de que no hay ningún tipo que se pueda completar paraA
que proporcione el tipo(_ => Unit) => ?
(Existencial_
no es un tipo).En el segundo caso,
process(_)
es una lambda; al escribir una lambda sin tipo de argumento explícito, Scala infiere el tipo del argumento queforeach
espera, y_ => Unit
es un tipo (mientras que simplemente_
no lo es), por lo que puede ser sustituido e inferido.Este bien puede ser el truco más complicado en Scala que he encontrado.
Tenga en cuenta que este ejemplo se compila en 2.13. Ignórelo como si fuera asignado para subrayar.
fuente
val x: Any = _
println _
yprintln(_)
son diferentes. Puede ver esto, por ejemplo, en que manejan tipos existenciales y polimórficos de manera ligeramente diferente. Veremos un ejemplo en un momento.De (mi entrada) en las Preguntas frecuentes , que ciertamente no garantizo que esté completa (agregué dos entradas hace solo dos días):
Esto también es parte de esta pregunta .
fuente
var i: Int = _
o el caso especial de coincidencia de patronesval (a, _) = (1, 2)
o el caso especial de val descartadofor (_ <- 1 to 10) doIt()
def f: T; def f_=(t: T)
combo para crear un miembro f mutable._
nombres de los métodos son trampas. Pero bueno, está bien. Solo espero que alguien más actualice las preguntas frecuentes ... :-)Una excelente explicación de los usos del guión bajo es la magia Scala _ [guión bajo] .
Ejemplos:
En Scala,
_
actúa de forma similar a*
Java al importar paquetes.En Scala, un getter y setter se definirán implícitamente para todos los vars no privados en un objeto. El nombre del captador es el mismo que el nombre de la variable y
_=
se agrega para el nombre del definidor.Uso:
Si intenta asignar una función a una nueva variable, la función se invocará y el resultado se asignará a la variable. Esta confusión ocurre debido a las llaves opcionales para la invocación del método. Deberíamos usar _ después del nombre de la función para asignarlo a otra variable.
fuente
List(1,2,3,4,5).foreach(print(_))
es mucho más fácil de hacerList(1,2,3,4,5).foreach(print)
, ni siquiera necesitas el guión bajo en absoluto, pero supongo que eso es solo una cuestión de estiloHay un uso que puedo ver que todos aquí parecen haber olvidado enumerar ...
En lugar de hacer esto:
Podrías simplemente hacer esto:
fuente
n => n
Aquí hay algunos ejemplos más donde
_
se usa:En todos los ejemplos anteriores, un guión bajo representa un elemento en la lista (para reducir, el primer guión bajo representa el acumulador)
fuente
Además de los usos que JAiro mencionó, me gusta este:
Si alguien necesita todas las propiedades de conexión, puede hacer:
Si solo necesita un host y un puerto, puede hacer:
fuente
Hay un ejemplo específico de que se usará "_":
puede ser igual a:
La aplicación de "_" en algunos escenarios se convertirá automáticamente en "(x $ n) => x $ n"
fuente