Своеобразный случай исчезновения данных - PullRequest
2 голосов
/ 27 мая 2019

Я пытаюсь следующий код:

import std.stdio; 
import std.range; 

void main(){
    auto data = [[1,2,3], [4,5,6]];     // putting auto instead of int[][] here makes no difference; 
    auto coldata =  data.transposed;
    writeln("coldata: ", coldata);          // prints ok; 
    writeln("transposed data: ", coldata);  // Empty list is printed. Data disappears/evaporates!
}

Вывод:

$ rdmd evapor.d
coldata: [[1, 4], [2, 5], [3, 6]]
transposed data: []

Во втором вызове печатается пустой список. Данные, кажется, просто исчезают / испаряются!

Почему данные не выводятся при втором вызове?

Редактировать: Пустой список печатается, даже если я звоню транспонировать каждый раз:

writeln("coldata: ", data.transposed);          // prints ok; 
writeln("transposed data: ", data.transposed);  // data disappears / evaporates! 

Также использование coldata.dup не работает. Выдает следующую ошибку:

soq_evapor.d(10): Error: template object.dup cannot deduce function from argument types !()(Transposed!(int[][], cast(TransverseOptions)0)), candidates are:
/usr/include/dmd/druntime/import/object.d(3169):        object.dup(T : V[K], K, V)(T aa)
/usr/include/dmd/druntime/import/object.d(3206):        object.dup(T : V[K], K, V)(T* aa)
/usr/include/dmd/druntime/import/object.d(4482):        object.dup(T)(T[] a) if (!is(const(T) : T))
/usr/include/dmd/druntime/import/object.d(4508):        object.dup(T)(const(T)[] a) if (is(const(T) : T))
Failed: ["/usr/bin/dmd", "-v", "-o-", "soq_evapor.d", "-I."]

1 Ответ

2 голосов
/ 27 мая 2019

Диапазон «расходуется».Если вам нужно повторно использовать его, как у вас, вам нужно обязательно позвонить save, прежде чем использовать его.

https://forum.dlang.org/post/migwtldccpwryusyolkq@forum.dlang.org https://forum.dlang.org/post/n2m1jl$2dqf$1@digitalmars.com

Вы можете найти больше информации об этом здесь: https://forum.dlang.org/thread/plsuntcmsezxpjbxkfnz@forum.dlang.org

import std.stdio; 
import std.range; 

void main(){
    auto data = [[1,2,3], [4,5,6]];     // putting auto instead of int[][] here makes no difference; 

    auto coldata =  data.dup();
    auto otherData =  data.dup();

    writeln("coldata: ", coldata.transposed);          // prints ok; 
    writeln("transposed data: ", otherData.transposed);  // this also prints ok.

}

является одним из таких способов сделать это.

Основная причина для этого заключается в том, как API разработан в D. Не все диапазоны деструктивно повторяются, это зависит только от вида.В общем, хотя вы можете.

На сайте D Lang есть следующее:

Большинство диапазонов в стандартной библиотеке являются структурами, поэтому итерация foreach обычно не является деструктивнойхотя и не гарантировано.Если эта гарантия важна, можно использовать специализацию InputRange - прямые диапазоны с методом .save:

https://tour.dlang.org/tour/en/basics/ranges

...