Нельзя Ломтик Взять!Р от ЗППП.диапазон в D?


Я пытаюсь использовать оператор slice для получения среза возвращаемого значения функции take из std.диапазон. Мой код:

auto tempChunk = ['a', 'b', 'c', 'd'];
auto a = tempChunk.take(3);
writeln(a[0..2]);

Как Взять!R в данном случае-это просто псевдоним для char [], я бы ожидал, что это будет компилироваться. Однако компилятор говорит мне, что Take!(char[]) cannot be sliced with []. Возьмем другой пример:

int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; 
auto s = arr.take(5);
writeln(s[0..4]);

Это будет компилироваться и выполняться без проблем, печать [1, 2, 3, 4, 5]. Я совершенно не понимаю, почему первый пример не будет работать, в то время как второй работает.

1 5
d2

1 ответ:

Шаблон Take использует hasSlicing, чтобы определить, можно ли вернуть фрагмент ввода вместо Take!R структура. Проверка фактических типов возвращаемых данных делает его немного более ясным:

import std.range, std.stdio;

void main()
{
    auto chararr = ['a', 'b', 'c', 'd'];
    auto a = chararr.take(3);
    writeln( typeid(typeof(a)) );

    auto intarr = [ 1, 2, 3, 4 ];  
    auto b = intarr.take(3);
    writeln( typeid(typeof(b)) );
}

// Output:
// std.range.Take!(char[]).Take
// int[]

HasSlicing явно предписано возвращать false для всех "узких строк" - тех, элемент которых может представлять не один символ, а кодовую точку (на основе char и wchar).

Итак, вот где начинаются мои размышления, но я полагаю, что это делается для предотвращения случайное создание искаженных строк UTF-8 & Co с помощью нарезки. Лучше использовать dchar [], если у вас нет реальной потребности в char[].