ZetCode

Dart runes

最后修改日期:2024 年 1 月 28 日

在本文中,我们将介绍如何在 Dart 中使用 runes。

字符串是 UTF-16 码单元的序列。字符串在程序中表示一些文本。一个字符可能由多个码点表示。每个码点可以有一个或两个码单元。码点是字符集中的数值偏移量。每个码点都是一个数字,其含义由 Unicode 标准给出。

字形是任何给定语言书写系统的最小单位。单个字形本身可能携带意义,也可能不携带意义,它可能对应于口语的单个音素,也可能不对应。术语字符曾用于表示原始 ASCII 表中的单个字符。然而,该表只能表示有限的字符集。在 ASCII 表之外,最好使用字形而不是字符。

rune 是一个整数,表示一个 Unicode 码点。字符串的 runes 属性返回其 runes。该术语取自 Go。字符串的 runes 属性返回字符串的 Unicode 码点。为了表示 Unicode 码点,使用了 \uXXXX 语法,其中 XXXX 是一个 4 位十六进制值。如果 Unicode 码点需要超过 4 位数字,我们将值放在花括号中。

字节是为字符串内容存储的实际信息。每个码点根据使用的 Unicode 标准(UTF-8、UTF-16 等)可能需要一个或多个字节的存储空间。

characters 包包含用于更高级的 Unicode 字形操作的函数。

Dart runes 简单示例

以下简单示例演示了如何使用 runes。

main.dart
void main() {
  final msg = 'an old falcon';
  print(msg.codeUnits);

  for (final rune in msg.runes) {
    print(rune);
  }
}

codePoints 属性返回一个码点列表,而 runes 属性提供了一个码点/runes 的可迭代对象。

$ dart main.dart
[97, 110, 32, 111, 108, 100, 32, 102, 97, 108, 99, 111, 110]
97
110
32
111
108
100
32
102
97
108
99
111
110

Dart String.fromCharCode

String.fromCharCode 将一个码点转换为一个字形。

main.dart
void main() {
  final msg = "one 🐘 and three 🐋";

  for (final rune in msg.runes) {
      stdout.write("${String.fromCharCode(rune)} ");
  }
}

在示例中,我们遍历字符串 runes。我们使用 String.fromCharCode 成员函数将每个 rune 转换为一个字形。

$ dart main.dart
o n e   🐘   a n d   t h r e e   🐋 

Dart emojis

以下示例显示了四个 emoji。

main.dart
void main() {
  final c1 = '\u{1F9F6}';
  final c2 = '\u{1FA86}';
  final c3 = '\u26C4';
  final c4 = '\u{1F37A}';

  print(c1);
  print(c2);
  print(c3);
  print(c4);

  print(c3.codeUnits);
  print(c4.codeUnits);
}

emoji 使用带有十六进制值的特殊语法表示。

$ dart emojis.dart
🧶
🪆
⛄
🍺
[9924]
[55356, 57210]

请注意,第四个 emoji 使用了两个码点。

Dart runes 长度

使用 length 属性,我们可以确定字符串的长度或相应 runes 属性的长度。

main.dart
void main() {
  final msg = 'one 🐘 and three 🐋';

  print(msg.length);
  print(msg.runes.length);
}

我们有一个由 ASCII 字符和两个 emoji 组成的字符串。

print(msg.length);
print(msg.runes.length);

我们访问字符串对象的 length 属性及其 runes 属性。

$ dart main.dart
19
17

runes.length 给出正确答案;字符串中有 17 个字形。

在下一个示例中,我们计算不同书写系统的字形数量。

main.dart
void main() {
  final msg1 = "falcon";
  final msg2 = "вишня";
  final msg3 = "🐺🦊🦝";
  final msg4 = "नमस्ते";

  print(msg1.length);
  print(msg2.runes.length);
  print(msg3.runes.length);
  print(msg4.runes.length);
}

在该程序中,我们计算 ASCII、西里尔文、梵文和 emoji 的字形数量。

$ dart main.dart
6
5
3
6

该示例给出了除梵文外的所有正确结果。对于更复杂的示例,我们需要使用 characters 包。

Dart characters

characters 包支持 Unicode(扩展)字形簇。

$ dart pub add characters

我们将包添加到项目中。

main.dart
import 'package:characters/characters.dart';

void main() {
  final m1 = "🐺🦊🦝";
  final m2 = "вишня";
  final m3 = "नमस्ते";

  print(m1.characters.length);
  print(m2.characters.length);
  print(m3.characters.length);

  print(m3.characters.first);
  print(m3.characters.last);

  for (final e in m3.characters) {
    print(e);
  }
}

在该程序中,我们计算 emoji、西里尔文和梵文文本的字形数量。

import 'package:characters/characters.dart';

已导入该包。

print(m1.characters.length);
print(m2.characters.length);
print(m3.characters.length);

该包为我们提供了 characters 属性。

print(m3.characters.first);
print(m3.characters.last);

我们获取梵文文本的第一个和最后一个字形。

for (final e in m3.characters) {
  print(e);
}

我们打印出它所有的字形。

$ dart main.dart
3
5
4
न
ते
न
म
स्
ते

现在我们得到正确的结果。

来源

Dart Runes - 语言参考

在本文中,我们介绍了 Dart runes。

作者

我叫 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。至今,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面有十多年的经验。

列出 所有 Dart 教程