Esta es una expresión común en los idiomas en los que los tipos no incluyen controles de rango. Un valor de "fuera de límites" se usa para indicar una de varias condiciones. Aquí, el valor de retorno indica dos cosas: 1) fue el carácter encontrado, y 2) dónde se encontró. El uso de -1 para not found
y un índice no negativo para found
codifica de forma sucinta estos dos en un valor, y el hecho de que not-found
no necesita devolver un índice.
En un lenguaje con estricta verificación de rango, tales como Ada o Pascal, el método puede implementarse como (pseudo código)
bool indexOf(c:char, position:out Positive);
Positive
es un subtipo de int, pero restringido a valores no negativos.
Esto separa la bandera encontrada/no encontrada de la posición. La posición se proporciona como un parámetro de salida, esencialmente otro valor de retorno. También podría ser un parámetro de entrada/salida para iniciar la búsqueda desde una posición determinada. El uso de -1 para indicar no encontrado no estaría permitido aquí ya que viola las verificaciones de rango en el tipo Positivo.
Las alternativas en Java son:
- lanzar una excepción: esta no es una buena opción aquí, ya que no encontrar un personaje no es una condición excepcional.
- divide el resultado en varios métodos, p.
boolean indexOf(char c); int lastFoundIndex();
. Esto implica que el objeto debe aferrarse al estado, que no funcionará en un programa simultáneo, a menos que el estado se almacene en un almacenamiento local de subprocesos o se use sincronización, todos los gastos generales considerables.
- devuelva la posición y encuentre el indicador por separado: como
boolean indexOf(char c, Position pos)
. Aquí, crear el objeto de posición puede verse como una sobrecarga innecesaria.
- crear un tipo de retorno de valores múltiples
como
class FindIndex {
boolean found;
int position;
}
FindIndex indexOf(char c);
aunque separa claramente los valores de retorno, sufre sobrecarga de creación de objetos. Algo de eso podría mitigarse pasando el FindIndex
como parámetro, p.
FindIndex indexOf(char c, FindIndex start);
Incidentalmente, múltiples valores de retorno iban a ser parte de java (roble), pero fueron despedido antes de 1.0 a reducir el tiempo de su liberación. James Gosling says desearía haber sido incluidos. Sigue siendo un wished-for feature.
Mi opinión es que el uso de valores mágicos es una forma práctica de codificar resultados de múltiples valores (un indicador y un valor) en un único valor de retorno, sin requerir excesiva sobrecarga de creación de objetos.
Sin embargo, si usa valores mágicos, es mucho mejor trabajar con ellos si son consistentes en todas las llamadas api relacionadas.Por ejemplo,
// get everything after the first c
int index = str.indexOf('c');
String afterC = str.substring(index);
Java insuficiente a este respecto, ya que el uso de -1 en la llamada a substring
causará un IndeOutOfBoundsException
. En cambio, podría haber sido más consistente para la subcadena devolver "" cuando se invoca con -1, si se considera que los valores negativos comienzan al final de la cadena. Los críticos de los valores mágicos para las condiciones de error dicen que el valor de retorno se puede ignorar (o suponer que es positivo). Una API apta que maneje estos valores mágicos de una manera útil reduciría la necesidad de verificar -1 y permitir un código más limpio.
posible duplicado de [abuso constante?] (Http: // stackoverflow.com/questions/1862593/constant-abuse). Esta pregunta discute cero de manera explícita pero 0 y -1 son tan comunes en muchos idiomas ... – gbn
Simplemente hágase un 'final int NOT_FOUND = -1;' y siga su camino feliz. Aparte de eso, ¿cuál es la desventaja de hacerlo de forma "-1"? –
@gbn: No veo nada de Josh Bloch en esa pregunta, así que no, no es una tontería. Y tampoco veo cómo esto es subjetivo/argumentativo. Las autoridades dicen una cosa u otra. Los libros prescriben de una manera u otra. Estos son los hechos que estoy buscando. – polygenelubricants