跳轉到內容

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 - 連線字串的有效方法

[編輯 | 編輯原始碼]
華夏公益教科書