不能切取!R从标准范围到D?

不能切取!R从标准范围到D?,d,phobos,D,Phobos,我试图使用slice操作符从std.range获取take函数返回值的一个切片。我的代码: auto tempChunk = ['a', 'b', 'c', 'd']; auto a = tempChunk.take(3); writeln(a[0..2]); 照你说的做!在本例中,R只是char[]的别名,我希望可以编译它。然而,编译器告诉我,Take!(字符[])不能用[]切片。。再举一个例子: int[] arr1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

我试图使用slice操作符从std.range获取take函数返回值的一个切片。我的代码:

auto tempChunk = ['a', 'b', 'c', 'd'];
auto a = tempChunk.take(3);
writeln(a[0..2]);
照你说的做!在本例中,R只是char[]的别名,我希望可以编译它。然而,编译器告诉我,
Take!(字符[])不能用[]切片。
。再举一个例子:

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]。现在我完全搞不懂为什么第一个示例不起作用,而第二个示例起作用。

take模板使用hassing来确定是否可以返回输入片段而不是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[]
Hassicing被明确指示为所有“窄字符串”返回false,这些字符串可能不代表单个字符,而是一个代码点(基于char和wchar的字符串)


现在,这里是我的推测的起点,但我认为这样做是为了防止使用切片意外创建格式错误的UTF-8&Co字符串。如果您对char[]没有任何实际需求,最好使用dchar[]。谢谢,这样就可以解决问题了。然而,Take结构定义了一个opIndex,但是当我尝试
writeln(a[0]),它不工作。这是什么原因?它仅为RandomAccessRange定义opIndex,而窄字符串则不是。老实说,我无法理解这个原理,因为窄字符串实际上可以通过本机切片作为随机访问代码点范围使用。这是个好问题。我建议使用d标记或同时使用d和d2,因为订阅d提要的人要多得多。@МаааСССааааааааааааааааа1072,因此,除非您知道自己在显式地处理字符串,否则切片无法工作,即使这样,通常也无法在O(1)中完成,因为您需要首先找到有效代码点的索引。这个答案和这个答案都讨论了这个问题。如果需要的话,请随时发布新问题。@JonathanMDavis是的,我知道推理,但问题是在某些情况下,字符串被视为代码点范围,我很难构建一致的设计方案:)(我已经在D.learn中开始了一个相关的线程)