2016-03-14 9 views
5

Когда я использую std.algorithm.copy на объектах std.digest, я получаю разные результаты по сравнению с использованием put байт по байтам. Зачем?std.algorithm.copy и std.digest

import std.stdio; 
import std.digest.digest; 
import std.digest.md; 
import std.algorithm; 

void main() { 
    string s = "Hello!\n"; 
    auto d1 = makeDigest!MD5; 
    auto d2 = makeDigest!MD5; 
    foreach (ubyte b; s) { 
     d1.put(b); 
    } 
    s.copy(d2); 
    writeln(digest!MD5(s).toHexString); 
    writeln(d1.finish().toHexString); 
    writeln(d2.finish().toHexString); 
} 

Выход:

E134CED312B3511D88943D57CCD70C83 
E134CED312B3511D88943D57CCD70C83 
D41D8CD98F00B204E9800998ECF8427E 

ответ

4

d2 передается по значению для копирования. Данные копируются внутри функции, но затем, когда она возвращается, переменная d2 на вне не изменяется!

Я вроде бы думаю, что это может быть ошибка: текущее поведение не имеет для меня большого смысла. Когда вы копируете его, имеет смысл сделать это по ссылке. Unittests тестируют только массивы, которые являются полуреференциями (они являются указателями), и они работают для них.

+1

Вот отчет об ошибке: https://issues.dlang.org/show_bug.cgi?id=9102 Я не помню, была ли какая-либо причина, почему копия не проходит диапазон по ссылке. Мы просто не указали, являются ли допустимые диапазоны выходных значений законными (и это явно не определено для InputRanges). Что-то, что должно было быть реализовано для дайджестов, - это отключить это (это), чтобы избежать тихого копирования. Но я предполагаю, что это уже поздно, так как это сломает и действительный код. – jpf

+2

В качестве обходного пути вы можете использовать MD5Digest (который является классом) вместо MD5 (который является структурой). – Thayne