Comment lire la saisie de l'utilisateur dans la Rouille?
Note de l'éditeur: Cette question fait référence à des parties de Rouille qui sont antérieurs à la Rouille 1.0, mais le concept général est toujours valide à Rust 1.0.
J'ai l'intention de faire un générateur de jetons. J'ai besoin de lire chaque ligne de l'utilisateur et arrêter de lire une fois que l'utilisateur appuie sur ctrl-D.
J'ai cherché et trouvé seulement un exemple sur la Rouille IO qui n'a même pas compiler. J'ai regardé la io
du module de documentation et a constaté que la read_line()
fonction est la partie de la ReaderUtil
interface, mais stdin()
renvoie une Reader
à la place.
Le code que je tiens essentiellement à ressembler à celui-ci en C++
vector<string> readLines () {
vector<string> allLines;
string line;
while (cin >> line) {
allLines.push_back(line);
}
return allLines;
}
Vous devez vous connecter pour publier un commentaire.
Dans la Rouille de 0,4, utilisez le
ReaderUtil
trait à l'accès à laread_line
fonction. Notez que vous avez besoin de convertir explicitement la valeur à un type de traits, par exemple,reader as io::ReaderUtil
stdin()
...)Rouille 1.x (voir la documentation):
La rouille de 0,10–0,12 (voir la documentation):
La rouille de 0,9 (voir 0.9 documentation):
Rouille 0.8:
Rouille 0.7:
for
boucle pourrait devenir plus simple à l'avenir (essentiellement de se débarrasser de.iter().advance
).for io::stdin().each_line |line| { .. }
, ou à l'aide deextra::fileinput
:for fileinput::input |line| { .. }
Au 17 avril 2015 à partir de
mdcox
sur la mozilla rouille irc.stdin.read_line(input);
, le compilateur me prévient à propos de cette ligne étant pas utilisé.La question est de lire des lignes à partir de stdin et le retour d'un vecteur. Sur La Rouille 1.7:
Il existe peu de moyens je pense.
Lire tous les commentaires en un seul
String
De lire des lignes dans
Vector
. Ce n'est pas dupanic
lors de la lecture d'une ligne ne parvient pas, au contraire, il ignore qui a échoué ligne.En outre, si vous souhaitez analyser:
Après l'avoir lu dans la chaîne de le faire. Vous pouvez l'analyser pour les autres collections qui implémente
FromIterator
. Les éléments contenus dans la collection doivent également mettre en placeFromStr
. Aussi longtemps que le trait contrainte satisfait, vous pouvez changer Vec toutCollection:FromIterator
,Collection<T: FromStr>
Vous pouvez aussi l'utiliser sur le
StdinLock
À Rust 1.0 et les versions ultérieures, vous pouvez utiliser le
lignes
méthode sur tout ce qui met en œuvre lastd::io::BufRead
trait pour obtenir un itérateur sur les lignes de l'entrée. Vous pouvez également utiliserread_line
, mais à l'aide de l'itérateur est plus probable que ce que vous voulez. Voici une version de la fonction en question à l'aide des itérateurs; voir ci-dessous pour une explication plus détaillée. (aire de jeux lien)Et voici une version qui ressemble plus à la version C++ dans la question, mais n'est pas vraiment le idiomatiques moyen de le faire dans de Rouille (aire de jeux):
Pour obtenir quelque chose qui implémente
BufRead
, qui est nécessaire pour appelerlines()
ouread_line()
, vous appelezstd::io::stdin()
pour obtenir un handle vers l'entrée standard, et ensuite appelerlock()
sur le résultat à obtenir le contrôle exclusif du flux d'entrée standard (vous devez avoir le contrôle exclusif d'obtenir unBufRead
, parce que sinon, la mise en mémoire tampon pourrait produire des résultats arbitraires si deux threads ont été la lecture de l'entrée standard stdin à la fois).De recueillir le résultat dans un
Vec<String>
, vous pouvez utiliser lecollecter
méthode sur un itérateur.lines()
renvoie un itérateur surResult<String>
, nous avons donc besoin de traiter les cas d'erreur dans lequel une ligne ne peut pas être lu; pour cet exemple, nous venons d'ignorer les erreurs avec unfilter_map
que seulement ignore les erreurs.Le C++ comme version utilise
read_line
, qui ajoute la ligne de lecture d'une chaîne de caractères, et nous avons ensuite pousser la corde dans notreVec
. Parce que nous transférer la propriété de la chaîne à laVec
quand nous faisons cela, et parce queread_line
serait autrement garder l'ajout à lastring
, nous avons besoin d'allouer une nouvelle chaîne pour chaque boucle (ce qui semble être un bogue dans l'original de la version C++ dans la question, dans lequel la même chaîne est partagé et donc ne s'accumulent chaque ligne). Nous utilisonsalors laissez -
de continuer à lire jusqu'à ce que nous avons touché une erreur, et nous casser si jamais nous lire zéro octets qui indique la fin de l'entrée.Euh... Après de nombreux essais et erreurs, j'ai trouvé une solution.
Je voudrais encore voir une meilleure solution, donc je ne vais pas accepter ma propre solution.
Le code ci-dessous imprime exactement ce que les entrées de l'utilisateur.
C'est ce que j'ai (avec l'aide de la gentillesse des gens dans le #rouille canal IRC sur irc.mozilla.org):
Et la preuve que ça marche 🙂
de https://doc.rust-lang.org/book/ch02-00-guessing-game-tutorial.html#processing-a-guess
Alors il ya beaucoup de façons différentes de le faire dans de rouille je pense que c'est le plus simple à mettre en œuvre.