GoldenCrystalLe 11/01/2015 à 00:23
Y'a un cas ou personnellement, j'aime bie utiliser goto, c'est pour écrire une fonction de traitement de texte type échappement de caractères (ou remplacement). En général on se trouve face à deux cas: soit y'a rien à modifier, soit y'a un truc à modifier, donc un cas où idéalement on n'alloue rien, soit y'a quelque chose à modifier, donc un cas où on alloue forcément au moins un nouveau buffer.
Y'a plusieurs façons d'écrire le code, mais par exemple:public static string DoubleQuotes(string text, char quote)
{
int i;
for (i = 0; i < text.Length; ++i)
if (text[i] == quote) goto DoDoubleQuotes;
return text;
DoDoubleQuotes: ;
var sb = new StringBuilder(text.Length + 2); // Chiffre magique pris presque au pif en espérant que ça marche bien la plupart du temps
sb.Append(text, 0, ++i).Append(quote);
int start = i;
for (; i < text.Length; ++i)
if (text[i] == quote)
sb.Append(text, start, -start + (start = i + 1)).Append(quote);
if (i > start)
sb.Append(text, start, i - start);
return sb.ToString();
}
Je met la version sans goto histoire de vous ménager un peu, mais j'aime moins: (Entre autres parce que ça fait un appel de méthode en plus et qu'on a pas souvent la chance d'avoir des optimisations tail call)public static string DoubleQuotes(string text, char quote)
{
for (int i = 0; i < text.Length; ++i)
if (text[i] == quote) return ReallyDoubleQuotes(text, quote, i);
return text;
}
private static string ReallyDoubleQuotes(string text, char quote, int i)
{
var sb = new StringBuilder(text.Length + 2); // Chiffre magique pris presque au pif en espérant que ça marche bien la plupart du temps
sb.Append(text, 0, ++i).Append(quote);
int start = i;
for (; i < text.Length; ++i)
if (text[i] == quote)
sb.Append(text, start, -start + (start = i + 1)).Append(quote);
if (i > start)
sb.Append(text, start, i - start);
return sb.ToString();
}
Et là y'a qu'une seule variable pour représenter l'état du parsing car c'est un cas simple (donc ça passe bien avec deux méthodes), mais c'est pas forcément toujours le cas.
(PS: J'ai écrit ce code sans le compiler ou le tester donc je garantis pas ne pas m'être foiré sur les calculs de plage de caractères)