D2에서 동적 배열을 약간 보았습니다. 이해하기가 어려웠습니다. 또한 사양을 잘못 해석하고있는 것 같습니다. 동적 배열의 참조 또는 슬라이스에서 작업하는 것은 배열을 변경할 때 매우 오류가 발생하는 것 같습니다 ... 아니면 기본 사항을 이해하지 못합니까? 이들이 동일한 배열을 기준으로참조가있는 동적 배열을 변경하는 것은 나쁜 습관입니까?
auto a = [1];
auto b = a;
assert(&a != &b); // different instance; Doesn't share length
assert(a.ptr == b.ptr); // same items
assert(a == [1]);
assert(a == b);
가 하나를 변경하면 다른 변경 : 오직 주 실물과 같은 배열을 참조
배열 사양에서
auto a = [1,2];
auto b = a;
a[1] = 20;
assert(a == [1,20]);
assert(a == b);
효율성을 극대화하기 위해 런타임은 항상 여분의 공간을 피하기 위해 배열의 크기를 조정하려고 시도합니다 복사. 새 크기가 더 크고 배열이 new 연산자 또는 이전 크기 조정 작업을 통해 할당되지 않은 경우에는 항상 복사본 을 수행합니다.
그래서 굳이 용 참조 중단하지 않는 길이를 변경 : 배열에의
병합은 항상 피연산자의 복사본을 생성, 경우에도 하나를
auto a = [1]; auto b = a; b.length = 2; assert(b == [1,0]); assert(a == [1]); // a unchanged even if it refers to the same instance assert(a.ptr == b.ptr); // but still the same instance // So updates to one works on the other a[0] = 10; assert(a == [10]); assert(b == [10,0]);
사양에서를 피연산자는 길이가 0 인 배열입니다.
auto a = [1];
auto b = a;
b ~= 2; // Should make a copy, right..?
assert(a == [1]);
assert(b == [1,2]);
assert(a != b);
assert(a4.ptr == b.ptr); // But it's still the same instance
a[0] = 10;
assert(b == [10,2]); // So changes to a changes b
하지만 배열이 서로 단계 것이다 때, 값이 깨진 새 위치와 기준에 복사 : 변경을하기 전에 두 배열의 길이를 변경
auto a = [1];
auto b = a;
b ~= 2;
assert(a == [1]);
assert(b == [1,2]);
a.length = 2; // Copies values to new memory location to not overwrite b's changes
assert(a.ptr != b.ptr);
은 상기와 같은 결과를 제공합니다 (나는 것)
auto a = [1];
auto b = a;
a.length = 2;
b.length = 2;
a[1] = 2;
assert(a == [1,2]);
assert(b == [1,0]);
assert(a.ptr != b.ptr);
그리고 같은 변화 길이 또는 cancatenating는 (나는 이것이 위의 주어진 기대 : 예상이) 위의 주어진
auto a = [1];
auto b = a;
b.length = 2;
a ~= 2;
assert(a == [1,2]);
assert(b == [1,0]);
assert(a.ptr != b.ptr);
그러나 그 다음에 조각들이 또한 그림에 들어오고 갑자기 더 복잡해집니다! 슬라이스는 ...
auto a = [1,2,3];
auto b = a;
auto slice = a[1..$]; // [2,3];
slice[0] = 20;
assert(a == [1,20,3]);
assert(a == b);
a.length = 4;
assert(a == [1,20,3,0]);
slice[0] = 200;
assert(b == [1,200,3]); // the reference to b is still valid.
assert(a == [1, 20, 3, 0]); // but the reference to a is now invalid..
b ~= 4;
// Now both references is invalid and the slice is orphan...
// What does the slice modify?
assert(a.ptr != b.ptr);
slice[0] = 2000;
assert(slice == [2000,3]);
assert(a == [1,20,3,0]);
assert(b == [1,200,3,4]);
을 고아가 될 수 그래서 ... 그것은 같은 동적 배열에 대한 다중 참조가 나쁜 관행인가? 그리고 주위에 조각을 건네주는거야? 아니면 D에서 동적 배열의 전체 점을 놓치고 있습니다.
좋은 답변에 감사드립니다. 또한 배열의 재 할당이 필요할 때까지 배열의 최대 길이를 지정할 수있는 .capacity 속성에 대해서도 들었습니다. "auto b = a"를 수행하면 다른 참조를 얻습니다. & a! = & b, 그러나 "is"는 .ptr을 참조 평등을 검사하기 위해 사용합니다. – simendsjo