跳转到内容

ooc 编程/字符串

来自维基教科书,开放世界中的开放书籍

字符串类型

[编辑 | 编辑源代码]

字符串类型在核心模块 lang/types 中定义。字符串字面量,例如 "abc",就是这种类型。

str := "This is a string literal"

在右侧,一个由字符串字面量表示的字符串对象被创建。它的引用被分配给变量 str。

默认情况下,一些运算符被重载用于字符串。例如,(+)被用作字符串连接运算符。例如

str := "I love" + " french cheese"
// is the same as
str := "I love french cheese"

(+)被重载用于几乎所有从 C 继承的类型(字符串、字符、数字类型),因此您可以执行以下操作

str := "The answer is " + 42

标准 SDK 中也重载了 [ ],用作切片运算符

"Sand" println()
// is the same as
"Sandwich"[0..4] println()

注意:切片运算符适用于字节,而不是字符。有关更多信息,请参见下面的 UTF-8 支持部分。

在字符串上重载了更多运算符,例如用于比较的 ==,用于重复的 *,用于边界检查修改的 [ ]= 等。

ooc 中的字符串不是不可变的,但标准类型 String 中的每个方法都会返回给定字符串的副本,并且永远不会修改原始字符串。

标准类型 String 提供了一套用于字符串操作的不错方法。由于它们都返回副本,因此您应该执行以下操作

 name = name trim() // remove whitespace at both ends

但决不能

 name trim() // wrong!

这将创建一个新的修剪后的字符串并将其丢弃。学习字符串类型并了解其方法以避免重复造轮子是很有益的。

UTF-8 支持

[编辑 | 编辑源代码]

在撰写本文时,ooc 中没有内置的 UTF-8 支持。length() 函数返回用于存储字符串的字节数,而不是字符数。

原因是 Unicode 标准中字符之间没有明确定义的边界。可以粗略地确定“音节群”,即用对应于字符的字形关联修饰符等,但这非常困难,并且存在非欧洲/非美国语言的边缘情况。

因此,目前还没有 UTF-8 字符、代码点等,但这并不妨碍在 ooc 程序中使用 UTF-8。ICU 和 utf8proc 库在处理 ooc 代码库中的这种编码问题方面尤其令人感兴趣。

请注意,语言设计在这方面并非最终确定,并且可能会在将来发生变化,只要其他更紧迫的问题得到解决。

字节长度

[编辑 | 编辑源代码]

由于缺乏 UTF-8 支持,length() 方法返回字节数,因此

"o/" length()

是 2,但是

"漢字" length()

是 6,因为构成日语单词“汉字”的每个字符都使用 3 个字节来存储。

创建新的字符串

[编辑 | 编辑源代码]

您可以从一个字符创建一个新的字符串

str := String new('\n')

或者只分配固定数量的字符

str := String new(128)

字符串字面量,例如 "abc",也是 String 类型。

str := "Curiosity killed the cat."

遍历字符串

[编辑 | 编辑源代码]

您可以遍历字符串的字节,因为它实现了 iterator() 方法。

for (c in "Hello, vertical world!") {
  c println()
}

比较字符串

[编辑 | 编辑源代码]

您可以使用 == 运算符比较两个字符串,因为它在 SDK 中被重载。它调用 equals() 方法,因此在 ooc 中

 name == "JFK"
 // is the same as
 name equals("JFK")

Java 不同,这种行为极大地提高了 ooc 代码的可读性。

您仍然可以通过先将它们强制转换为指针来比较字符串的地址

 // equals won't be called here
 name as Pointer == otherName

compare 方法可用于测试字符串部分的相等性,例如

 "awesome" compare("we", 1, 2) // is true
 "Turn right" compare("Turn left", 0, 6) // is false

子字符串和切片

[编辑 | 编辑源代码]

[ ] 运算符可以与范围一起使用,以获得与调用 substring 相同的效果

 // both these statements are true
 "happiness"[3..6] == "pin"
 "happiness" substring(3, 6) equals("pin")

在字符串中搜索

[编辑 | 编辑源代码]

indexOf() 和 lastIndexOf() 方法分别允许搜索另一个字符串中字节或字符串的第一个和最后一个出现位置。

 str := "Proud of you, son."
 // returns 6
 str indexOf("of") toString() println()
 // returns 15
 str lastIndexOf('o') toString() println()

重复字符串

[编辑 | 编辑源代码]

可以使用重载的(*)运算符或 times() 方法将字符串重复多次。

 // these lines print the same thing
 println("The cake is a lie!" * 5)
 "The cake is a lie!" times(5) println()

请注意,由于优先级,我们无法编写

 // wrong!
 "The cake is a lie!" * 5 println()

因为编译器会将其解读为

 "The cake is a lie" * (5 println())

这肯定不是我们的本意。

反转字符串

[编辑 | 编辑源代码]

可以使用 reverse 方法反转字符串。

 // prints 'lebon nob el'
 "le bon nobel" reverse() println()

请注意,reverse() 处理的是字节,而不是字符。有关更多信息,请参见 UTF-8 支持部分。

追加字符串

[编辑 | 编辑源代码]

您可以使用 ( + ) 运算符或 append() 和 prepend() 方法

 // results in the string "indirect"
 "in" + "direct"
 "in" append("direct")
 "direct" prepend("in")

与所有其他字符串方法一样,将返回一个副本,原始字符串不会被修改。

但是,如果您要从许多较小的部分构建字符串,最好使用 Buffer,如下面所述。

StringTokenizer - 分割字符串

[编辑 | 编辑源代码]

Buffer - 连接字符串的有效方法

[编辑 | 编辑源代码]
华夏公益教科书