2013-07-25 4 views
3

:문자열 분할 나는 D를 배우고 문자열을 분할하려고

import std.stdio; 
    import std.string; 

    auto file = File(path, "r"); 
    foreach (line; file.byLine) { 
      string[] parts = split(line); 

이 함께 컴파일에 실패 :

Error: cannot implicitly convert expression (split(line)) of type char[][] to string[] 

이 작동을 :

auto file = File(path, "r"); 
    foreach (line; file.byLine) { 
      char[][] parts = split(line); 

그러나 char[][]을 사용해야하는 이유는 무엇입니까? 지금까지 설명서를 이해하는 한 splitstring[]을 반환한다고 말합니다.

답변

5

split(line.idup);

split은 템플릿 함수이며 반환 유형은 인수에 따라 다릅니다. file.byLine.front은 성능상의 이유로 다시 사용되는 char[]을 반환합니다. 따라서 현재 루프 반복 이후에 필요한 파트가 필요한 경우 dup 또는 idup을 사용해야합니다.

+0

이 솔루션을 사용하여 성능에 영향이 있습니까? – clstaudt

+0

'idup'은 배열의 불변 복제를 만듭니다. 따라서 이것이 중요하다면, 필요하다면 항상 불변으로 변환 할 수 있습니다. 예 : std.algorithm의'map'으로'foreach (line; file.byLine.map! "cast (string) a")'를 호출합니다. 그러나 일반적으로 불변 캐스트에주의하십시오. –

+2

당신이하고있는 일을 정말로 알지 못한다면, 당신은 불변의 것을 버려서는 안됩니다. 그렇게하면 형식 시스템이 파괴되어 예기치 않은 동작이 발생할 수 있습니다. 이 예제에서 루프 반복을 통해 문자열을 저장하면 'byLine'이 사용한 것과 동일한 임시 버퍼를 계속 가리킬 것이기 때문에 문자열을 "값을 변경"할 수 있습니다. –

0

std.stdio.lines을 사용할 수 있습니다. foreach 루프의 변수를 입력하는 방법에 따라 반복 할 때마다 새 버퍼를 할당하거나 이전 버퍼를 다시 사용합니다. 이렇게하면 .dup/.idup을 저장할 수 있습니다.

하지만 어떤 유형을 선택해야할지는 유스 케이스에 달려 있습니다 (즉, 데이터를 얼마나 오래 필요로하는지).

foreach(string line; lines(file)) { // new string every iteration } 

foreach(char[] line; lines(file)) { // reuse buffer } 

utf8 검증이 비활성화됩니다 ubyte 대신 char의 사용.