Evgenii Legotckoi
Evgenii Legotckoi25. Juni 2016 02:22

Benutzerhandbuch #09 - Ruby - Iteratoren

Iteratoren sind kein originelles Konzept in Ruby. Sie sind in objektorientierten Sprachen üblich. Wird auch in Lisp verwendet, obwohl sie nicht als Iteratoren bezeichnet werden. Das Konzept der Iteratoren ist jedoch vielen ungewohnt und muss daher näher erläutert werden.

Das Verb iterieren bedeutet, etwas oft zu tun, und Sie wissen, dass ein Iterator etwas ist, das etwas oft tut.

Wenn wir Code schreiben, müssen wir in vielen Situationen mit Schleifen arbeiten. In C verwenden wir * für * oder * while. * Zum Beispiel:

char *str;
for (str = "abcdefg"; *str != '\0'; str++) {
  /* здесь идёт обработка символа */
}

In C bietet die * for (...) -Syntax eine Abstraktion, um beim Erstellen einer Schleife zu helfen, aber die Überprüfung von str * auf ein * Null-Zeichen * erfordert, dass der Programmierer die Details der internen Struktur des Strings kennt. Dies erweckt den Eindruck, dass C eine Low-Level-Sprache ist. Hochsprachen sind für ihre flexiblere Zeichenfolgenunterstützung bekannt. Betrachten Sie das folgende Shell-Skript sh*:

#!/bin/sh

for i in *.[ch]; do
  # ... here would be something to do for each file
done

Alle C-Quell- und Header-Dateien werden im aktuellen Verzeichnis verarbeitet, und der Shell-Befehl verarbeitet die Dateidetails, indem er die Dateinamen einzeln aufnimmt und ändert. Dieses Niveau ist höher als C, oder?

Aber es gibt noch mehr zu beachten: Während dies großartig für eine Sprache ist, die Iteratoren für integrierte Datentypen bereitstellt, sind wir frustriert, wenn wir wieder Low-Level-Schleifen für unsere eigenen Datentypen schreiben müssen. In OOP definieren Benutzer oft andere Datentypen, was ernsthafte Probleme verursachen kann.

Die objektorientierte Sprache beinhaltet also einige Möglichkeiten zur Iteration. Einige Sprachen bieten dafür spezielle Klassen an. Ruby ermöglicht es Ihnen, Iteratoren direkt zu definieren.

Ruby-String hat einige nützliche Iteratoren:

ruby> "abc".each_byte{|c| printf "<%c>", c}; print "\n"
<a><b><c>
   nil
  • jedes \ _byte * ist ein Iterator für jedes Zeichen in der Zeichenfolge. Jedes Zeichen wird in eine lokale Variable * c * gelegt. Dies könnte in etwas ähnliches wie C-Code übersetzt werden ...
ruby> s="abc";i=0
   0
ruby> while i<s.length
    |    printf "<%c>", s[i]; i+=1
    | end; print "\n"
<a><b><c>
   nil

... jedoch ist der Iterator * each \ _byte * konzeptionell einfacher und besser geeignet, um auch dann weiterzuarbeiten, wenn die Klasse String in Zukunft radikal modifiziert wird.Einer der Vorteile von Iteratoren besteht darin, dass sie robuster gegenüber solche Veränderungen. Was eigentlich eine gute Eigenschaft des Codes ist. (Ja, sei geduldig, wir werden mehr darüber sprechen, was Klassen sind)

Ein weiterer * String * Iterator ist * jede \ _line.

ruby> "a\nb\nc\n".each_line{|l| print l}
a
b
c
   nil

Aufgaben, die C-Programmieraufwand erfordern (String-Trennzeichen finden, Teilstrings erstellen usw.) sind mit Iteratoren einfacher zu handhaben.

Die im vorigen Kapitel eingeführte * for-Anweisung * iteriert wie der Iterator * each . Die Zeichenfolge * each * funktioniert wie * each \ _line , schreiben wir das folgende Beispiel mit * für * neu:

ruby> for l in "a\nb\nc\n"
    |   print l 
    | end
a
b
c
   nil

Wir können eine Kontrollstruktur * wiederholen * in Verbindung mit Schleifeniterationen verwenden, und dies wird die aktuelle Iteration an die Spitze der Schleifeniterationen zurückgeben.

ruby> c=0
   0
ruby> for i in 0..4
    |   print i
    |   if i == 2 and c == 0
    |     c = 1
    |     print "\n"
    |     retry
    |   end
    | end; print "\n"
012
01234
   nil

Manchmal sehen Sie die Anweisung * yield * in einer Iteratordefinition. Yield verschiebt die Kontrolle an den Codeblock, der an den Iterator übergeben wurde (dies wird im Kapitel zur Objektbehandlung ausführlich behandelt). Das folgende Beispiel zeigt einen * Repeat * Iterator, der einen Codeblock so oft wiederholt, wie in einem Argument angegeben.

ruby> def repeat(num)
    |   while num > 0
    |     yield
    |     num -= 1
    |   end
    | end
   nil
ruby> repeat(3) { print "foo\n" }
foo
foo
foo
   nil

Mit retry können wir einen Iterator definieren, der wie eine while-Schleife funktioniert, obwohl dies zu langsam ist, um praktisch zu sein.

ruby> def WHILE(cond)
    |   return if not cond
    |   yield
    |   retry
    | end
   nil
ruby> i=0; WHILE(i<3) { print i; i+=1 }
012   nil

Verstehen Sie, was ein Iterator ist? Es gibt einige Einschränkungen für die ursprünglichen Iteratoren, aber tatsächlich ist es oft praktisch, geeignete Iteratoren zu definieren, wenn Sie einen neuen Datentyp definieren. In diesem Fall sind die obigen Beispiele nicht sehr hilfreich. Wir können darüber sprechen, wenn wir besser verstehen, was Klassen sind.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
A
ALO1ZE19. Oktober 2024 08:19
Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken