鑽進 Firefox OS 開發:淺談 Internal string

鑽進 Firefox OS 開發:淺談 Internal string

不論是哪個語言的程式設計師,都時常需要和語言或是框架的字串 (String) 打交道。舉凡傳遞訊息、寫 log,或當作資訊來儲存等等都會用到今天就來和大家聊聊Firefox OS 裡面,string 是怎麼被使用的。

Internal string / External string

首先要提到的是,我們稱在 Mozilla codebase 中所用到的字串為 “internal string”,而對外的字串類別則稱為 “external string”。由於我大部分時間都在改動 Mozilla codebase,所以本文主要針對 internal string 所寫,參考自 MDN 上的 Mozilla internal string guide 以及我個人的開發經驗,若您是 Extention 或是 XULRunner app 的開發者,想知道字串怎麼使用,請見 MDN 上的 Mozilla external string guide 這篇文章。

ns[C]String

如果你看過 Firefox OS 內部的 Gecko 程式碼,你會找到兩種比較常見的 String 類別: nsString nsCString。它們的差別在於 nsString 用來存放寬字元 (wide character16-bit)nsCString 則是存放窄字元 (narrow character8-bit)。實際的應用中,我們常常需要對兩者做轉換,而其間的轉換必須透過特別的 helper classes 或是 helper methods,想直接把 nsCString 的物件轉型成 nsString 是無效的,反之亦然。更多詳情請見 Unicode Conversion ns*CString vs. ns*String

ns[C]String 是字串類別的實作,事實上在函式間的介面,我們會宣告傳送的是 nsAString/nsACString,也就是 nsString/nsCString 的基底類別(base class). 兩個類別中間都多了個 A,即 abstract 之意,可以看出它們是兩個抽象類別(abstract class)(註)。在實作 DOM API 的時候,常會需要在 IDL 裡定義字串參數,此時,若使用 C++ 實作這個 IDL,則用來接收這個字串參數的類別就是 nsA[C]String,詳見 IDL String types 一節。

nsAuto[C]String

nsAuto[C]String 是一個繼承自 ns[C]String 的類別,這兩者最大的不同點在於 ns[C]String 會把 buffer 放在 heap,但 nsAuto[C]String 則是會在 stack 上先配置一個 64 個字元大小的空間。顯而易見的,如果你的字串少於 64 個字元,那麼用 nsAuto[C]String 就可以省去執行時期的動態配置時間。反過來說,如果指定一個大於 64 個字元長度的字串給 nsAuto[C]String 變數,就必須另外配置一塊 heap 上的 buffer,這種情況下請直接使用 ns[C]String

Literal String

Literal String 指的是寫在程式碼裡面的字串。例如我們會寫 LOG(“Connecting failed”),則 “Connecting failed” 便是一個 Literal String。我們有時會想要呼叫一個函式,它需要一個 ns[C]String 字串參數,但我們卻想要傳 literal string,該怎麼辦呢? 其實只要透過 NS_LITERAL_[C]STRING() 這個巨集就可以將 literal string 轉成 ns[C]StringMDN 上提供了很清楚的範例

// call Init(const PRUnichar*)

Init(NS_LITERAL_STRING(“start value”).get());

// call Init(const nsAString&)

Init(NS_LITERAL_STRING(“start value”));

// call Init(const nsACString&)

Init(NS_LITERAL_CSTRING(“start value”));

宣告字串成員變數 (member variable) 時的注意事項

當我們定義了一個類別,且這個類別必須持有字串時,請宣告這個變數為 ns[C]String,而不要宣告成字串物件的指標 ns[C]String*。這是因為 ns[C]String 其實是非常小的物件,與其在建構子中再 new 出一個 ns[C]String 物件,不如直接宣告物件實體。

另一個常見的錯誤是在類別內宣告一個 nsAuto[C]String 的成員變數,上面我們提到 nsAuto[C]String 會預留一塊 64 字元寬度的 buffer 在其內部,因此這也會造成此類別的物件變得過大,使用上請務必小心。

 

想要知道更多和 internal string 相關的功能以及 API 嗎?請參考 Mozilla internal string guide 或是 xpcom/string/public/nsTSubstring.h 這個標頭檔。

 

註:隨著時間演變,nsA[C]String 已經不是抽象類別了,但仍舊是 ns[C]String 的基底類別。

掌握最新 Firefox, Firefox OS 相關訊息

加入 Mozilla Taiwan 臉書粉絲團 

加入 Mozilla Taiwan  G+ 

瀏覽 Mozilla Taiwan 部落格 

官網 mozilla.com.tw