operators - ¿Operador de exclamación?
(3)
Estoy aprendiendo D y he visto un montón de código como este:
ushort x = to!ushort(args[1]);
Asumo que esto arroja args[1]
a ushort
, pero ¿cuál es la diferencia entre esto y cast(ushort)
?
EDITAR: ¿Y qué otros usos tiene el operador de signo de exclamación?
El signo de exclamación aquí no es un operador, es solo una parte simbólica de la sintaxis de creación de instancias de la plantilla explícita (se describe en detalle here ).
std.conv.to
( docs ) es una plantilla de función para convertir entre tipos arbitrarios. Se implementa completamente en la biblioteca y no tiene soporte especial en el idioma. Tiene un alcance más amplio y diferente en comparación con el operador de yeso.
La plantilla a toma dos parámetros de tipo; un tipo "a" y un tipo "desde", en ese orden. En su ejemplo, la plantilla se crea una instancia explícita con el argumento de tipo único ushort
para el parámetro "a", y una segunda string
argumento de tipo (suponiendo que args
proviene del primer parámetro a main
) se deduce automáticamente del argumento de función regular que se pasa al función ( args[1]
) como el parámetro "desde".
La función resultante toma un parámetro de cadena y devuelve un ushort analizado de esa cadena, o lanza una excepción si falla. El operador de yeso no intentará este tipo de conversión de alto nivel.
Tenga en cuenta que si hay más de un parámetro de plantilla explícito, o ese parámetro tiene más de un token ( ushort
es un token de una sola palabra clave), debe ajustar la lista de parámetros de la plantilla entre paréntesis:
ushort result;
result = to!(typeof(result))(args[1]);
En este ejemplo, typeof
, (
, result
y )
son cuatro tokens separados y, por lo tanto, se requieren los paréntesis.
Para responder a tu última pregunta, el !
El token también se usa para el operador unario, no relacionado con las instancias de la plantilla:
bool yes = true;
bool no = !yes; // ''no'' is false
En D,
to!ushort(args[1])
Es taquigrafía para la creación de instancias de plantilla.
to!(ushort)(args[1])
y es similar a
to<ushort>(args[1])
en lenguajes como C ++ / Java / C #.
El signo de exclamación es observar el hecho de que no es un argumento regular, sino un argumento de plantilla.
La notación no usa paréntesis angulares porque son ridículamente difíciles de analizar correctamente para un compilador (hacen que la gramática sea muy sensible al contexto), lo que hace que sea mucho más difícil implementar un compilador correcto. Vea here para más información.
El único otro uso que conozco es simplemente la operación ''no'' unaria (por ejemplo, false == !true
) ... No puedo pensar en ningún otro uso en este momento.
Respecto al reparto:
cast(ushort)
es un lanzamiento no seleccionado, por lo que no lanzará una excepción si el valor está fuera de rango.
to!ushort()
es una conversión marcada , por lo que lanza una excepción si el valor está fuera de rango.
Ya tienes dos respuestas excelentes de jA_cOp y Merhdad. Solo quiero responder directamente a la pregunta de OP ( ¿cuál es la diferencia entre esto y cast (ushort)? ) - La diferencia es que cast(ushort)args[1]
no funcionará (no se puede convertir desde una cadena a una uint como that), mientras que la plantilla to!(type)(param)
sabe qué hacer con la cadena y cómo convertirla al tipo primitivo.