Нельзя Ломтик Взять!Р от ЗППП.диапазон в 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 ответ:
Шаблон 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[].