"In language x strings are y - e.g. UTF-16 - by default" - 这是什么意思?
"In language x strings are y - e.g. UTF-16 - by default" - what does that mean?
在很多地方我们都可以读到,例如"C# uses UTF-16 for its strings" (link)。从技术上讲,这意味着什么?
我的源文件只是一些文本。假设我正在使用 Notepad++ 编写一个简单的 C# 应用程序;在我保存文件后,文本在磁盘上的字节表示方式取决于 N++,所以这可能不是人们的意思。这是否意味着:
- 编译器输入编码为 UTF-16 的语言规范requires/recommends?
- 标准库函数是编码感知的,并将字符串视为 UTF-16,例如
String
的运算符 []
(returns 第 n 个 字符而不是第n个字节)?
- 编译器生成可执行文件后,其中存储的字符串是 UTF-16 格式吗?
我以 C# 为例,但这个问题适用于任何可以说它对其字符串使用编码 Y 的语言。
"C# uses UTF-16 for its strings"
据我对这个概念的理解,这充其量只是一种简化。 CLI 运行时(例如 CLR)需要存储它从程序集加载的字符串或在内存中以 UTF-16 编码在运行时生成的字符串 - 或者至少将它们呈现给运行时的其余部分和应用程序。
参见 CLI 规范:
III.1.1.3 Character data type
A CLI char type occupies 2 bytes in memory and represents a Unicode code unit using UTF-16
encoding. For the purpose of stack operations char values are treated as unsigned 2-byte integers
(§III.1.1.1)
和 C# 规范:
4.2.4 The string type
Instances of the string class represent Unicode [being UTF-16 in .NET jargon] character strings.
我无法很快找到 C# 编译器支持哪些文件编码,但我很确定您可以将源文件存储为 UTF-8 编码,甚至 ASCII(或其他非 unicode 代码页) ).
The standard library functions are encoding-aware and treat the strings as UTF-16
不,BCL 只是将字符串视为 字符串 ,作为 char[]
数组的包装器。只有在运行时之外进行转换时,例如在 P/Invoke 调用中,运行时才“知道”要调用哪些平台函数以及如何将字符串编组到这些函数。例如参见 [=16=]
Once the compiler produces an [assembly], the strings are stored inside it in UTF-16?
是的。
让我们看看C/C++ char 类型。它是 8 位长(1 字节)。这意味着它可以存储 255 个不同的符号。现在让我们想想字体到底是什么。它有点像地图。从 0 到 255(1 个字节)的值映射到符号。这些类型的字体通常包含两种类型的字符(例如西里尔字母和拉丁字母)和特殊符号。没有足够的 space(255 个限制)来保存希腊文或中文字母。
现在让我们看看什么是UTF-8。它是编码,它存储一些符号使用 8 位,一些使用 16 位。例如,如果您在记事本中键入单词 "word" 并使用 UTF-8 编码保存文件,则生成的文件将正好是 4 个字节的长度,但是如果您键入单词“дума”,这也是 4 个符号,它将使用 8 个字节在你的存储上。所以一些字母存储为 1 个字节,其他的为 2 个字节。
UTF-16 表示所有符号都存储在 2 个字节中,逻辑上 UTF-32 = 4 个字节。
让我们从编程的角度看看这看起来如何。当您在记事本中键入符号时,它们存储在 RAM 中(以记事本可以理解的某种格式)。当您将文件保存在磁盘上时,记事本在磁盘上写入一个字节序列。这些顺序取决于所选的编码。当您阅读(使用 C# 或其他语言)文件时,您必须知道它的编码。了解它,您将知道如何解释磁盘上写入的序列。
在很多地方我们都可以读到,例如"C# uses UTF-16 for its strings" (link)。从技术上讲,这意味着什么? 我的源文件只是一些文本。假设我正在使用 Notepad++ 编写一个简单的 C# 应用程序;在我保存文件后,文本在磁盘上的字节表示方式取决于 N++,所以这可能不是人们的意思。这是否意味着:
- 编译器输入编码为 UTF-16 的语言规范requires/recommends?
- 标准库函数是编码感知的,并将字符串视为 UTF-16,例如
String
的运算符[]
(returns 第 n 个 字符而不是第n个字节)? - 编译器生成可执行文件后,其中存储的字符串是 UTF-16 格式吗?
我以 C# 为例,但这个问题适用于任何可以说它对其字符串使用编码 Y 的语言。
"C# uses UTF-16 for its strings"
据我对这个概念的理解,这充其量只是一种简化。 CLI 运行时(例如 CLR)需要存储它从程序集加载的字符串或在内存中以 UTF-16 编码在运行时生成的字符串 - 或者至少将它们呈现给运行时的其余部分和应用程序。
参见 CLI 规范:
III.1.1.3 Character data type
A CLI char type occupies 2 bytes in memory and represents a Unicode code unit using UTF-16 encoding. For the purpose of stack operations char values are treated as unsigned 2-byte integers (§III.1.1.1)
和 C# 规范:
4.2.4 The string type
Instances of the string class represent Unicode [being UTF-16 in .NET jargon] character strings.
我无法很快找到 C# 编译器支持哪些文件编码,但我很确定您可以将源文件存储为 UTF-8 编码,甚至 ASCII(或其他非 unicode 代码页) ).
The standard library functions are encoding-aware and treat the strings as UTF-16
不,BCL 只是将字符串视为 字符串 ,作为 char[]
数组的包装器。只有在运行时之外进行转换时,例如在 P/Invoke 调用中,运行时才“知道”要调用哪些平台函数以及如何将字符串编组到这些函数。例如参见 [=16=]
Once the compiler produces an [assembly], the strings are stored inside it in UTF-16?
是的。
让我们看看C/C++ char 类型。它是 8 位长(1 字节)。这意味着它可以存储 255 个不同的符号。现在让我们想想字体到底是什么。它有点像地图。从 0 到 255(1 个字节)的值映射到符号。这些类型的字体通常包含两种类型的字符(例如西里尔字母和拉丁字母)和特殊符号。没有足够的 space(255 个限制)来保存希腊文或中文字母。
现在让我们看看什么是UTF-8。它是编码,它存储一些符号使用 8 位,一些使用 16 位。例如,如果您在记事本中键入单词 "word" 并使用 UTF-8 编码保存文件,则生成的文件将正好是 4 个字节的长度,但是如果您键入单词“дума”,这也是 4 个符号,它将使用 8 个字节在你的存储上。所以一些字母存储为 1 个字节,其他的为 2 个字节。
UTF-16 表示所有符号都存储在 2 个字节中,逻辑上 UTF-32 = 4 个字节。
让我们从编程的角度看看这看起来如何。当您在记事本中键入符号时,它们存储在 RAM 中(以记事本可以理解的某种格式)。当您将文件保存在磁盘上时,记事本在磁盘上写入一个字节序列。这些顺序取决于所选的编码。当您阅读(使用 C# 或其他语言)文件时,您必须知道它的编码。了解它,您将知道如何解释磁盘上写入的序列。