Delphi 2009 RawByteString变幻莫测

Mar*_*ski 5 delphi unicode utf-8 delphi-2009 rawbytestring

假设出于某些不正当的原因,您希望显示UTF8String的原始字节内容.

var
  utf8Str : UTF8String;
begin    
  utf8Str := '€?????ó???';
end;
Run Code Online (Sandbox Code Playgroud)

(1)这不行,它显示可读形式:

memo1.Lines.Add( RawByteString( utf8Str ));
// output: '€?????ó???'
Run Code Online (Sandbox Code Playgroud)

(2)然而,这确实"有效" - 请注意连接:

memo1.Lines.Add( 'x' + RawByteString( utf8Str ));
// output: 'x€ąćę?‚?„???›????'
Run Code Online (Sandbox Code Playgroud)

我理解(1),虽然编译器强制转换为UnicodeString似乎阻止了原样显示RawByteString var.但是,为什么行为会在(2)中发生变化?

(3)陌生人仍然 - 让我们扭转连接:

memo1.Lines.Add( RawByteString( utf8Str ) + 'x' ); 
// output: '€?????ó???x'
Run Code Online (Sandbox Code Playgroud)

我一直在阅读Delphi中新奇的字符串类型,并认为我理解它们是如何工作的,但这是一个难题.

Bar*_*lly 9

RawByteString仅存在以最小化AnsiString与具有不同代码页亲和度的各种风格的s一起工作的函数所需的重载次数.

通常,不要声明类型的变量RawByteString.不要将值类型转换为该类型.不要对该类型的变量进行连接.关于你唯一能做的事情是:

  • 声明此类型的参数(原始意图)
  • 索引这样的参数
  • 在这样的参数中搜索
  • 使用该StringCodePage功能检查字符串实际代码页的智能操作.

例如,您将注意到StringCodePage函数本身使用RawByteString其参数类型.这样,它可以与任何方法一起使用AnsiString,而不是在将其作为参数传递之前进行代码页翻译.

对于你的情况,像连接这样的东西很大程度上是不确定的.RTM和Update 2之间的行为发生了变化,但是当RTL字符串连接函数接收到具有不同代码页的多个字符串时,没有简单的方法可以找出应该用于最终字符串的代码页.这就是为什么你不应该像在这里那样连接它们的原因之一.