goto es una declaración de salto poderosa. Puede saltar a cualquier lugar en el mismo ámbito de acción. Puedes usar goto para personalizar tu flujo lógico, incluso usarlo para simular la recursividad, la iteración y la selección.
Sintaxis
Hay dos maneras de usar goto en C#:
- goto in switch: es la única manera de que una caja no vacía pase a otra caja en el interruptor C#.
- goto con etiqueta: Primero, etiquetamos una declaración por nombre_etiqueta: declaración;, luego podemos ir a esta declaración por nombre_etiqueta. La etiqueta de la sentencia debe ser definida en el mismo ámbito de acción.
goto in switch
Practiquemos goto in switch con el siguiente ejemplo de programador trabajador:
12345678910111213141516 estado de la cuerda ="hambriento";switch(estado){caso "normal": Console.WriteLine("coding..");gotodefault;// salta a la rama por defecto "hungry": Console.WriteLine("eat some stuff");gotocase "normal";// saltar a la rama "normal" branchcase "illness": Console.WriteLine("see a doctor");break;default: Console.WriteLine("ir a dormir");break;}
csharp
Si el estado es «hambriento», primero procesa la lógica del caso «hambriento», luego salta a la rama «normal», y finalmente cae en el default.
123 come algo de stuffcoding..ve a dormir
goto con Label
Para goto con etiqueta, los usos más apropiados están saltando en múltiples bucles anidados o condiciones.
Hemos aprendido que la ruptura sólo puede tener efecto en el bucle actual en los bucles anidados. Una idea sencilla es usar una bandera para marcar el estado, y procesarlo en bucles externos.
Aquí hay una versión de bucles anidados con bandera:
12345678910111213141516171819202122232425int[,,] arr =newint[2,3,2]{{{{1,2},{3,4},{5,6}},{{{7,8},{9,10},{11,12}}};bool flag =falso;for(int i =0; i < arr. GetLength(0);++i){for(int j =0; j < arr.GetLength(1);++j){for(int k =0; k < arr.GetLength(2);++k){if(arr[i, j, k]==7){ flag =true;break;} Console.WriteLine("el elemento actual es {0}", arr[i, j, k]);}if(flag)break;}if(flag)break;}Console.WriteLine("romper múltiples bucles cuando el valor es 7");
csharp
Esta es la versión con goto:
12345678910111213for(int i =0; i < arr.GetLength(0);++i){for(int j =0; j < arr.GetLength(1);++j){for(int k =0; k < arr. GetLength(2);++k){if(arr[i, j, k]==7)goto Finish; Console.WriteLine("el elemento actual es {0}", arr[i, j, k]);}}}Finish: Console.WriteLine("romper múltiples bucles cuando el valor es 7");
csharp
Bastante conciso y elegante, ¿verdad?
Otros usos
Excepto por los dos usos principales mencionados, aquí hay algunos otros usos.
Podemos considerar el goto como la forma de personalizar nuestro flujo de control, como la simulación de la recursividad, la iteración y la selección.
Usamos «do-while» como ejemplo para mostrar cómo usar «goto» para simular:
12345678910// do-while templatedo{ code_block;}while(condition);// reescrito por gotoLoop: code_block;if(condition)goto Loop;
csharp
Aquí está la declaración de para el resto en pitón. Si no se rompe el bucle, ejecutará la parte restante.
123456para x inrange(5):if x ==3:print("find 3 in loop")breakelse:print("not find 3 in loop")# llegar allí cuando no break
pitón
C# no apoyan para otra cosa, pero podemos lograrlo con goto fácilmente.
12345678910for(int i =0; i <5;++i){if(i ==3){ Console.WriteLine("find 3 in loop");goto Finish;}}}Consola.WriteLine("not find 3 in loop");Finish: Console.WriteLine("fin del bucle");
csharp
Pero estos usos no son recomendables. Discutiremos el efecto secundario de Goto más tarde.
Efecto secundario
Una vez que se inventa el goto, las discusiones nunca se detienen. Me refiero a las famosas opiniones de wiki goto:
Aquí hay un ejemplo negativo de goto, con el código de los espaguetis retorcido:
12345678910// ejemplo negativo de goto, codigo enmarañadoint x =0;Label1: x +=1;if(x %2==0)goto Label1;if(x %3==0)goto Label2;Console.WriteLine(x);Label2:if(x <10)goto Label1;
csharp
La legibilidad es horrible. Está débilmente estructurada y es difícil de depurar o mantener.
Mi sugerencia es: