2009-05-08 16 views
11

me gustaría poner en práctica la siguiente lógica:AS3: declarar un parámetro de "indefinido" para int, uint o número

function setMyValue (myVar:int = undefined):void 
{ 
    if (myVar == undefined) 
    { 
     /* Generate a value for myVar */ 
    } 
    else 
    { 
     /* Use the supplied value for myVar */ 
    } 
} 

lo tanto, si se suministra el valor, lo utilizan. Si no, generarlo. Parece lo suficientemente simple.

El problema es que a AS3 no le gusta esto. 'indefinido' se coacciona en '0', por lo que myVar nunca está indefinido. Probé variaciones con NaN, nulo, etc., pero nada funcionó. El único inconveniente que puedo pensar de improviso es proporcionar algún 'número mágico' para usar como predeterminado, pero eso es feo. Alguien sabe una mejor solución?

Gracias!

+0

Ah, OK, número es ligeramente diferente. El número predeterminado es NaN, por lo que esa instancia se puede manejar con isNaN (myVar). Sin embargo, quiero resolver para int y uint. – Wikiup

Respuesta

14

UPD (de mi comentario): Ciertamente, no es una buena práctica para recoger algunas número mágico para indicar el valor ausencia, a menos que pueda estar completamente seguro de que este número mágico no aparecería como consecuencia de alguna aritmética (que generalmente es verdad). Entonces, el mejor enfoque aquí es usar un tipo más ancho que int (por ejemplo, Number), o pasar un indicador (valor Boolean) para funcionar, así como int, para indicar la ausencia del valor real. La elección debe depender de si desea enfatizar la importancia del hecho de que el valor pasado es integral.


Si se siente cómodo con la expansión de tipo de argumento, entonces debe usar NaN y hace esto:

function setMyValue (myVar : Number = NaN) : void 
{ 
    if (isNaN(myVar)) 
    { 
     /* Generate a value for myVar */ 
    } 
    else 
    { 
     /* Use the supplied value for myVar */ 
    } 
} 

Eso es tanto más técnicamente precisa y también es más estable. También le permitirá escribir fuertemente en tiempo de compilación y no causar errores extraños como en el caso de usar Object.

Tenga en cuenta que esto no funcionará con int como sugiere una de las respuestas. int tiene solo valores numéricos, y NaN se verá forzado a 0. Tendrá que utilizar el tipo Number.

Si le preocupa el rendimiento, no lo haga. El uso de Number en lugar de int o uint es generalmente correcto.


UPD: Si desea marcan explícitamente que el argumento debe ser integral sólo tiene que utilizar la bandera adicional y el tipo exacto - que sería mucho más claro.

function setMyValue (isIntValueSupplied : Boolean = false, intValue : int = 0) : void 
{ 
    if (isIntValueSupplied) 
    { 
     /* Generate or use a default value of intValue */ 
    } 
    else 
    { 
     /* Use the supplied value for intValue */ 
    } 
} 

Otra opción es definir su propio tipo con un valor adicional, por ejemplo, MaybeInt, que contiene un valor entero y un indicador (si fue realmente inicializado o no). De esa forma, usted indicará claramente que el valor debe ser integral o sin valor. Sin embargo, este enfoque puede ser un poco voluminoso.

+0

Esto ciertamente se está acercando, ya que al menos sabré que es un número que viene a través del param (que luego puedo volver a moldear para un int/uint), pero tiene el mismo problema que mi preocupación con la respuesta de dirkgently. ¿Es realmente más limpio encasillar para el tipo de datos incorrecto? Tal vez simplemente estoy pidiendo algo que no se puede hacer de una manera verdaderamente limpia. Por cierto, esto no tiene nada que ver con el rendimiento per se. Simplemente intento establecer un enfoque de mejores prácticas para este problema. ¡Gracias por la ayuda! – Wikiup

+0

@Wikiup: Ciertamente, no es una buena práctica elegir algún número mágico para indicar la ausencia de valor, a menos que pueda estar completamente seguro de que este número mágico no aparecerá como resultado de algunos aritméticos (que generalmente es cierto). Entonces, el mejor enfoque aquí es usar un tipo más ancho que 'int' (por ejemplo,' Number'), o pasar un indicador (valor 'Boolean') para funcionar, así como' int', para indicar la ausencia del valor real. La elección debe depender de si desea enfatizar la importancia del hecho de que el valor pasado es integral. – dragonfly

+0

Creo que su comentario brinda una mejor solución de "mejores prácticas" que su respuesta original. Estoy de acuerdo en que los números mágicos rara vez son una buena idea (eso fue, después de todo, el objetivo de mi publicación original). la función setMyValue (useSuppliedValue: Boolean = false, suppliedValue: int = 0), mientras que Wordier parece proporcionar un formato menos ambiguo para el método; esto me parece una respuesta bastante sólida. Si desea editar su respuesta y escribirla como tal, con gusto comprobaré "responder" y le acreditaré los puntos de rep. : c) Muchas gracias! – Wikiup

2

¿El valor generado es const? Si es así, ¿por qué no simplemente tener esto como el valor predeterminado?

El problema es que a AS3 no le gusta esto. 'indefinido' se coacciona en '0', por lo que myVar nunca está indefinido.

Sí, porque, este es el valor de inicialización por defecto para int (por string y Object this'd ser null).

La otra opción es escribir libremente el parámetro como una Object o mantenerlo sin especificar (mediante el uso de un *) y más tarde en él encasillado a int si es no null.

function setMyValue (myVar:Object = null):void 
{ 
    if (myVar == null) 
    { 
     /* Generate a value for myVar */ 
    } 
    else 
    { 
     int value = myVar as int; 
     /* Use the supplied value for myVar */ 
    } 
} 
+0

Apreciar la respuesta rápida. El valor generado no es una const; necesita generarse en el momento en que se llama al método. Supongo que mi pregunta sería: ¿escribir de manera suelta es más limpio que usar un número mágico? Hacerlo de la manera en que sugieres significaría que tendría que borrar los datos para asegurarme de que no me entregan un valor ilegal (cadena/número/micrófono). Al menos usando el número mágico, un desarrollador sabría el tipo de datos requerido. Solo pensaría que debe haber una manera más limpia de hacer esto. – Wikiup

+0

Por cierto, te amé en "Long Dark Tea Time ..."; c) – Wikiup

2

Mi solución fue usar simplemente esto

if(myUint == new uint){ is undefined, act appropriately; } 
+0

El problema es que (new uint == 0) se resuelve en verdadero. Entonces, realmente solo estás probando si myUint == 0. –

0
function setMyValue (myVar:int = -1):void 
{ 
    if (myVar == -1) 
    { 
     /* Generate a value for myVar */ 
    } 
    else 
    { 
     /* Use the supplied value for myVar */ 
    } 
} 
Cuestiones relacionadas