problème. Quel est le résultat de
countOnes (int [])
lors de l'appel de
main (...)
dans le code Java ci-dessous (je n'ai pas envie de brancher) Alors n'hésitez pas à)?
SwitchSample.java
public class SwitchSample {
public static int countOnes(int[] numbers) {
int counter = 0;
for(int number : numbers) {
switch(number) {
case 0:
System.out.println("ZERO");
break;
case 1:
counter++;
default:
}
}
System.out.println("ONEs: " + counter);
return counter;
}
public static void main(String[] args) {
System.out.println("count: " + countOnes(new int[] { 1, 2, 3, 2, 1, 0, 3, 2, 1, 0, 4}));
}
}
Si vous pensez que la réponse est 2, c'est dommage car vous frappez 0 '' en comptant le nombre de
1 '' dans le tableau et sortez de la `` pause; Cependant, je suis tombé dans un piège.
Pause après 2 lignes de;Est**Échapper à l'instruction switch**Il n'échappe pas à la boucle for.
Par conséquent, l'apparition de `` 0 '' dans le tableau n'affecte pas le traitement de la boucle, donc` `` `countOnes (int [])` `` `est le nombre de tous les` `1 ''` dans le tableau. La réponse est 3 parce que ça compte.
Si vous omettez le `` `break;` `après le`` case 0: ``, l'instruction switch "échouera" et sera exécutée après le` `case 1:` ``, 1 Non seulement il comptera le nombre de zéros.
#### **`Après la pause pour éviter les "retombées";Il peut y avoir des critiques qui devraient être écrites, mais peu importe si ce n'est pas le cas.`**
```case 1
En regardant cet exemple, ne pensez-vous pas, "Pourquoi l'instruction qui s'échappe de la boucle est-elle la même que l'instruction qui s'échappe de l'instruction switch?" Je pense.
Quoi qu'il en soit, la question est: "Dans ce cas, comment dois-je écrire le code pour sortir de la boucle?"
Si vous modifiez le code comme suit, l'instruction switch sortira de la boucle avec `` `` case 0: `` ``, et la réponse à la première question deviendra 2.
#### **`SwitchSample.java`**
```java
public class SwitchSample {
public static int countOnesBeforeZero(int[] numbers) {
int counter = 0;
loop: for(int number : numbers) {
switch(number) {
case 0:
System.out.println("ZERO");
break loop;
case 1:
counter++;
default:
}
}
System.out.println("ONEs: " + counter);
return counter;
}
}
La seule différence est que le bloc de l'instruction for est étiqueté (boucle) et spécifié dans l'instruction break. C'est facile, mais les étiquettes de bloc sont rarement nécessaires, donc je suis sûr qu'il y a pas mal de programmeurs Java qui disent qu'ils n'ont pas écrit ou ne connaissent pas la grammaire. J'avais aussi un vague souvenir de grammaire, et chaque fois que je l'écrivais, je cherchais en ligne.
En premier lieu, la spécification de l'instruction switch dérivée du langage C selon laquelle si l'instruction break n'est pas écrite dans l'instruction switch, elle est exécutée en «passant» à l'instruction après l'étiquette de cas suivante est également «instruction d'une seule étiquette de cas». Il est facile de provoquer l'illusion d'un programmeur que "seul est exécuté", et a créé un grand nombre de bogues en raison de l'oubli d'écrire l'instruction break. Pour cette raison, «fallthrough» lui-même est considéré comme un anti-modèle de programmation dans les temps modernes, et la plupart des langages de programmation qui sont devenus populaires ces dernières années n'adoptent pas l'instruction switch qui provoque «fallthrough» dans les spécifications du langage. C'est presque la dernière génération de langages de programmation que JavaScript et PHP traversent, et Java est le deuxième plus ancien.
J'ai écrit un peu ci-dessus, "Pourquoi l'instruction qui s'échappe de la boucle et l'instruction qui s'échappe de l'instruction switch est-elle la même?", Mais c'est une instruction qui contrôle le flux dans lequel l'instruction switch est positionnée à proximité de la boucle, par exemple en langage C. Il semble que la raison en soit que Java a hérité de l'idée qu'il est naturel de consacrer une pause pour s'échapper. Cependant, d'un autre côté, alors que l'instruction goto était utilisée pour sortir de plusieurs boucles à la fois en langage C, pourquoi ne pas ajouter l'instruction goto à Java conçue à l'époque où l'idée de «programmation structurée» se généralisait? Au lieu de cela, j'ai créé le concept de "bloc étiqueté" et j'ai rendu possible (probablement) de sortir du bloc en spécifiant l'étiquette avec break. Cela a changé la fonctionnalité de l'instruction break en Java, donc je pense que je n'aurais pas dû utiliser le même mot réservé que la boucle d'échappement pour échapper à l'instruction switch.
Le temps a passé et Kotlin a été développé en tant que langage pour Java Virtual Machine (JVM). La déclaration de commutateur fall-through qui n'a pas été adoptée même dans Scala, le langage de la JVM de la génération précédente, n'est pas adoptée dans Kotlin, et elle peut être utilisée comme un commutateur amélioré comme une «expression» comme le cas-quand de Ruby. L'expression quand a été introduite. L'expression when n'exécute pas plusieurs blocs, et son comportement est if (...) {...} else if (...) else if (...) {...} else {.. C'est presque la même chose que l'écriture.} (Dans Kotlin, les instructions if peuvent également être utilisées comme expressions).
Étant donné que l'expression when ne tombe plus, il n'y a plus de rupture dans la spécification de l'expression when et il n'est pas nécessaire de s'inquiéter de la confusion avec l'instruction break qui sort de la boucle. Par conséquent, le code "compte le nombre de 1, mais quitte la boucle et termine le processus lorsqu'il atteint zéro" peut être écrit comme suit.
SwitchSample.kt
object SwitchSample {
fun countOnesBeforeZero(numbers: IntArray): Int {
var counter = 0
for(number in numbers) {
when(number) {
0 -> {
println("ZERO")
break
}
1 -> {
counter++
}
else -> {}
}
}
println("ONEs: $counter")
return counter
}
@JvmStatic
fun main(args: Array<String>) {
println("count: " + countOnes(intArrayOf(1, 2, 3, 2, 1, 0, 3, 2, 1, 0, 4)))
}
}
Vous pouvez construire avec succès avec Kotlin 1.4, qui vient de sortir une version stable l'autre jour.
Cependant, dans Kotlin 1.3 et ci-dessous
'break' and 'continue' are not allowed in 'when' statements. Consider using labels to continue/break from the outer loop
Un message d'erreur apparaît et la construction échoue. "Vous ne pouvez pas utiliser break and continue dans une instruction when. Pensez à utiliser des étiquettes pour continuer / interrompre les boucles." ???
Ne paniquez pas. Si, pour une raison quelconque, votre environnement de développement ne peut pas être mis à jour vers Kotlin 1.4, veuillez écrire:
SwitchSample.kt
object SwitchSample {
fun countOnesBeforeZero(numbers: IntArray): Int {
var counter = 0
loop@ for(number in numbers) {
when(number) {
0 -> {
println("ZERO")
break@loop
}
1 -> {
counter++
}
else -> {}
}
}
println("ONEs: $counter")
return counter
}
}
Comme pour la solution Java, étiquetez le bloc que vous souhaitez échapper et spécifiez-le dans l'instruction break, et il se construira normalement.
Les informations pratiques de cet article sont
--Label est requis si vous souhaitez utiliser une interruption de contrôle de boucle dans l'instruction de commutation Java
C'est juste (sourire amer).
[Ici](https://kotlinlang.org/docs/reference/whatsnew14.html#using-break-and-continue-inside] explique pourquoi break / continue ne peut pas être utilisé sans étiquette sous Kotlin 1.3. -when-expressions-included-in-loops) (bien que je ne pense pas que ce soit une explication suffisante).
Si vous écrivez la même logique avec if ~ else if ~ else sans utiliser when, cette restriction n'existe pas, et break / continue peut être utilisé sans étiquette, même dans Kotlin 1.3 ou inférieur. À titre de test, utilisez la fonction «Convertir l'expression if en expression when» d'Android Studio, écrivez la logique à l'aide de l'instruction break sans étiquette dans l'expression if, puis convertissez l'expression if en expression when. C'était. Ensuite, le bloc de boucle a été automatiquement étiqueté et une instruction break avec cette étiquette est apparue.
L'étiquette a également été donnée lorsque j'ai essayé cette conversion avec le plug-in Android Kotlin 1.4, qui ne devrait pas nécessiter d'étiquette. Même si les spécifications linguistiques changent dans Kotlin 1.4, le processus de conversion ne semble pas changer pour le moment.
Récemment, le nombre d'écritures de code Java a considérablement diminué, et il est proche de la situation où Kotlin devrait être utilisé, donc si vous oubliez d'étiqueter les instructions break in when sous Kotlin 1.3, vous obtiendrez une erreur. Il semble que cela devrait sortir et le corriger. Cependant, si vous omettez le libellé requis pour l'interruption dans l'instruction de commutation Java, aucune erreur ne se produira et la signification changera de manière significative, alors faites attention aux programmeurs qui écrivent du code Java.
Quand j'utilisais break dans une instruction switch dans une boucle, je pensais que la question "Quelle instruction est la pause?" Est susceptible de se produire dans divers langages de programmation, c'est pourquoi j'ai écrit cet article. Par conséquent, j'ai écrit quelques sujets sur les langages de programmation autres que Java et Kotlin, mais je ne suis pas un passionné de langage de programmation, donc je voudrais laisser Java et Kotlin comme la responsabilité principale pour le moment et laisser les autres langages à d'autres auteurs. pense.
Cependant, lorsque j'ai cherché sur le net, je n'ai trouvé aucun contenu qui m'inquiétait de la rupture de l'instruction switch dans la boucle. En ce sens, cet article peut être très original (rires), mais lorsque la plupart des programmeurs voient une rupture dans une instruction switch, même si elle se trouve à l'intérieur d'une boucle, «Cette rupture s'échappe de la boucle. Ce n'est peut-être pas un problème car il est rarement mal interprété car "cela peut être une pause à faire". Quand je suis arrivé à ce point, j'ai réalisé que j'avais peu de souvenir d'avoir des problèmes avec ce problème. Vous ne pouvez donc pas vous attendre à ce que plus de gens tombent dans le piège du problème au début (sourire amer).
What's New in Kotlin 1.4.0 - Using break and continue inside when expressions included in loops [instruction switch-Wikipedia](https://ja.wikipedia.org/wiki/Switch instruction)
Recommended Posts