Es gibt mehrere Möglichkeiten Iterierte über Objekte in D.
One zu tun ist, um die InputRange API zu implementieren. Eingabebereiche ähneln Iteratoren, haben jedoch eine andere API. Das Implementieren einer Bereichsschnittstelle bedeutet, dass Sie alle std.range
/std.algorithm
-Funktionen für Ihr Objekt verwenden können, z. B. map
, array
, joiner
und so weiter.
D hat keine __iter__
Funktion, um einen Iterator aus beliebigen Auflistungen zu erhalten. Daher müssen Sie eine Funktion implementieren, die einen Eingabebereich zurückgibt.
import std.range;
auto bytes() {
return chain(mime, data, header.serialize);
}
Dies wird einen ubyte
Eingangsbereich zurückzukehren, in mime
den Bytes besteht, in data
von dem Bytes gefolgt, dann in header.serialize
.
können Sie auch die opApply
Methode auf Ihrer Struktur implementieren. opApply
funktioniert nur mit foreach
, so dass Sie keine Entfernungsmethoden damit verwenden können, aber Sie können Dinge tun, wie den Schleifenkörper in separaten Threads ausführen.
Der Kern von opApply
ist, dass D den Schleifenkörper an opApply
als eine Funktion übergibt; das heißt, foreach(x; myObj) { body }
wird in umgewandelt.
void opApply(void delegate(ubyte[] part) loopbody) {
loopbody(mime);
loopbody(data);
loopbody(header.serialize());
}
Anstatt jedoch eine dieser beiden Optionen, empfehle ich, dass Sie eine Funktion auf Ihrem Objekt zu implementieren, das einen Ausgangsbereich und schreibt die Daten in es dauert.
Ein Ausgabebereich ist ein Objekt, das andere Objekte akzeptiert und ihnen etwas antut. In diesem Fall sollte der Ausgabebereich ubyte
s annehmen, sodass er einem Ausgabestream ähnelt.
void serialize(Range)(ref Range outRange) if(isOutputRange!(Range, ubyte)) {
put(outRange, mime); -- `put` simply feeds data into the output range
put(outRange, data);
header.serialize(outRange); // No longer have to allocate/return a ubyte array
}
Beispiel für die Verwendung, die die Ausgabe in eine Appender
speichert, die in ein Array umgewandelt werden kann:
import std.array;
auto serializedDataAppender = appender!ubyte();
myMsg.serialize(serializedDataAppender);
auto serializedData = serializedDataAppender.data;
Wenn Sie einen Leistungsbereich auf Ihre Steckdose implementieren, dann bedeutet das, dass die Ausgabebereich Lösung muss keinen Speicher aus dem Heap zuordnen.
Schauen Sie sich das Programming in D Buch (genauer gesagt, den Rang und Weitere Bereiche Abschnitte) für Informationen darüber, wie Sie Ihre eigenen Bereiche zu implementieren.
Wie in der Dokumentation angegeben (http://dlang.org/spec/statement.html#ForeachStatement) gibt es viele Möglichkeiten, mit foreach Aussagen umgehen. Am einfachsten ist vielleicht der Eingabebereich, aber ohne eine klare Übersicht darüber, was Sie bei jeder Wiederholung wünschen, ist es schwer zu sagen, welcher Weg für Ihren Fall am besten ist. Könntest du präziser sein? – cym13