루아의 문자열은 변경 불가능합니다. 즉, 문자열의 텍스트를 대체하는 솔루션은 결국 원하는 내용으로 새 문자열을 구성해야합니다. 단일 문자를 다른 내용으로 바꾸는 특별한 경우에는 원래 문자열을 접두사 부분과 접미사 부분으로 분할하고 새 내용을 중심으로 다시 연결해야합니다.
코드에이 변화 :
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
루아를 간단하게 할 수있는 가장 직접적인 번역이다. 아마도 대부분의 경우 충분히 빠릅니다. 접두어가 첫 번째 pos-1
문자 여야한다는 버그를 수정했으며 string.sub
의 마지막 인수가 누락 된 경우 해당 문자열의 끝에 해당하는 -1
으로 간주된다는 사실을 이용했습니다.
가비지 콜렉션이 문자열을 저장할 때까지 문자열 저장소에 임시 문자열이 여러 개 생성된다는 점에 유의하십시오. 접두어와 접미사의 임시 변수는 어떤 솔루션에서도 피할 수 없습니다. 그러나 이것은 또한 첫 번째 ..
연산자가 임시로 소비해야합니다.
두 가지 대체 방법 중 하나가 더 빠를 수도 있습니다. 첫 번째는 solution offered by Paŭlo Ebermann이지만, 하나의 작은 비틀기와 함께 :
는
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
이것은 별도의 임시 개체를 필요없이 최종 버퍼 크기를 추측 할 수있는 희망에 결과의 조립을 할 string.format
을 사용합니다.
그러나 은 %s
형식을 통과하는 모든 문자열에서 \0
문자와 관련된 문제가 발생할 수 있습니다. 특히 표준 C의 sprintf()
함수로 구현되므로 \0
의 첫 번째 발생시 대체 문자열을 종료 할 것으로 예상하는 것이 타당합니다. (의견에 의해 Delusional Logic 사용자에 의해 고지.)
떠오르는 세번째 대안이있다 :
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat
효율적 최종 결과에 문자열 목록을 연결. 선택적인 두 번째 인수는 문자열 사이에 삽입 할 텍스트로 여기에 기본값 인 ""
이 삽입됩니다.
내 생각 엔 문자열이 크지 않고이 대체를 자주하지 않으면 이러한 방법간에 실제 성능 차이가 나타나지 않을 것입니다. 그러나 저는 이전에 놀랐습니다. 따라서 응용 프로그램의 프로필을 작성하여 병목 현상이 있는지 확인하고 잠재적 솔루션을 신중하게 벤치마킹하십시오.
깊이있는 설명 주셔서 감사합니다 – dotminic
이것은 오래되었습니다. 하지만 내가 작성한 코드에서 사소한 버그를 해결했습니다. ''replace_char2'' 메쏘드는 널 (''\ 0'') 문자를 삽입하지 않는다는 것을 알았습니다. –
@DelusionalLogic 좋은 지적입니다. 'string.format'은 표준 C의'sprintf()'함수를 기반으로하며 NUL 바이트가 내장 된 문제가있을 수 있습니다. – RBerteig