Có một số cách để làm điều lặp trên các đối tượng trong D.
Một là để thực hiện các InputRange API. Phạm vi đầu vào tương tự như các trình lặp, nhưng có một API khác. Triển khai giao diện dải ô có nghĩa là bạn có thể sử dụng tất cả các chức năng std.range
/std.algorithm
trên đối tượng của mình, chẳng hạn như map
, array
, joiner
và v.v.
D không có chức năng __iter__
để nhận trình lặp từ bộ sưu tập tùy ý, do đó bạn cần triển khai hàm trả về phạm vi nhập.
import std.range;
auto bytes() {
return chain(mime, data, header.serialize);
}
này sẽ trả về một loạt ubyte
đầu vào, bao gồm các byte trong mime
, tiếp theo là các byte trong data
, sau đó trong header.serialize
.
Bạn cũng có thể triển khai phương pháp opApply
trên cấu trúc của mình. opApply
sẽ chỉ hoạt động với foreach
, vì vậy bạn không thể sử dụng các phương pháp phạm vi với nó, nhưng nó cho phép bạn thực hiện những việc như thực thi vòng lặp trong các chuỗi riêng biệt.
Ý chính của opApply
là D chuyển phần thân vòng lặp tới opApply
làm hàm; nghĩa là, foreach(x; myObj) { body }
được chuyển thành myObj.opApply((x) { body })
.
void opApply(void delegate(ubyte[] part) loopbody) {
loopbody(mime);
loopbody(data);
loopbody(header.serialize());
}
Tuy nhiên, thay vì một trong những lựa chọn, tôi khuyên bạn nên thực hiện một chức năng trên đối tượng của bạn mà phải mất một khoảng đầu ra và ghi dữ liệu vào nó.
Phạm vi đầu ra là đối tượng chấp nhận các đối tượng khác và thực hiện điều gì đó với chúng. Trong trường hợp này, dải đầu ra phải chấp nhận ubyte
s, làm cho nó tương tự như một luồng đầu ra.
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
}
sử dụng Ví dụ, lưu trữ đầu ra vào một Appender
, có thể được chuyển đổi thành một mảng:
import std.array;
auto serializedDataAppender = appender!ubyte();
myMsg.serialize(serializedDataAppender);
auto serializedData = serializedDataAppender.data;
Nếu bạn thực hiện một loạt sản lượng trên ổ cắm của bạn, thì đó có nghĩa là giải pháp dải đầu ra không phải cấp phát bộ nhớ nào từ heap.
Check-out cuốn sách Programming in D (đặc biệt là các Ranges và More Ranges phần) để biết về cách thực hiện dãy riêng bạn.
Như đã nêu trong tài liệu hướng dẫn (http://dlang.org/spec/statement.html#ForeachStatement) có rất nhiều cách để đối phó với tuyên bố foreach. Cách dễ nhất có thể là phạm vi đầu vào, nhưng không có một cái nhìn rõ ràng về những gì bạn muốn mỗi lần lặp lại trả về thì khó có thể biết cách nào là tốt nhất cho trường hợp của bạn. Bạn có thể chính xác hơn không? – cym13