天天看點

swift c語言 字元串的長度,在 Swift 中截取 C 字元串

作者:Joe,Cee

Swift 中的字元串處理一直都在變化,一直不斷發展。在研究 Swift 中某些字元串執行操作的演變過程中,我注意到了 Joel Spolsky 十幾年前寫的這個回答變得毫無用處。

下面的代碼無法正常工作,但是如果可以,那真是極好的:

var helloWorld = "Hello, world!"

let hello = helloWorld[0...4]

print(hello)

我的意思是,既然 Python 可以這樣用:hello = helloWorld[0:5],為什麼在 Swift 中不可以這樣用呢?

就像我們說的,Swift 2 很認真地聽取了 Joel 在 2003 年提出的那些建議,我們所有人都(痛苦地)發現字元串完全變樣了。mikeash.com 很好地總結了這些變化,是以對我來說,沒有必要再去比較字元 (Character) 和字母 (Grapheme) 的差別。而當我「了解」到這點後,毫無疑問加重了我的記憶量。為了從一個(我已經知道)ASCII 編碼的 const char* C 語言風格字元串中截取子串,我需要努力記住那些需要調用的黑科技代碼。是以,我不會費心費力地去記這些東西,而是把它們寫在這裡,不僅是為了我,也是為了大家。

簡單的子串示例

我一直在尋找一種方法,能夠在我的 Day-to-day Linux 任務中加入更多的 Swift 程式設計機會。我認為這是使用快速腳本 (quick script) 和面向 DevOps 的任務來替代 語言 的絕佳機會。在這種情況下,我希望有一個快捷的方法能夠列印出一個 Swift 開源項目的所有 git 修訂版本 (revision),下面是我的代碼:

import Glibc

func getGitRevision(dirname:String) -> String {

let BUFSIZE = 128

let cwd = String.fromCString(getcwd(nil, 0))!

var rc = chdir(dirname)

guard rc == 0 else {

return "ERROR"

}

var rev = ""

let pipe = popen("/usr/bin/git rev-parse HEAD", "r")

var buf = [CChar](count:BUFSIZE, repeatedValue:CChar(0))

while fgets(&buf, Int32(BUFSIZE), pipe) != nil {

rev = String.fromCString(buf)!

}

rev = rev[rev.startIndex...rev.startIndex.advancedBy(9)]

chdir(cwd)

return rev

}

let dirs = ["swift", "llvm", "clang", "lldb", "cmark", "llbuild", "swiftpm", "swift-corelibs-xctest", "swift-corelibs-foundation", "swift-integration-tests"]

for dir in dirs {

let rev = getGitRevision(dir)

print("\(dir):\(rev)")

}

我用 rev = rev[rev.startIndex...rev.startIndex.advancedBy(9)] 來擷取 Git 修訂版本哈希值的前 10 個字元,這實在是太啰嗦了,但是如果你正在處理的是 C 語言風格的字元串,那它可以很好地完成任務。

擴充

幸運的是,Swift 支援擴充,這個絕佳的特性允許你向不是你寫的、并且無法通路源代碼的類中添加一些方法。很多人在 Gist 上釋出了類似的擴充代碼,給通路子字元串添加一個小小的文法糖:

extension String {

subscript (r: Range) -> String {

get {

let startIndex = self.startIndex.advancedBy(r.startIndex)

let endIndex = self.startIndex.advancedBy(r.endIndex)

return self[Range(start: startIndex, end: endIndex)]

}

}

}

通過我們的擴充,我們就可以這樣寫:

let helloWorld = "Hello, world!"

var hello = helloWorld[0...4]

print(hello)

生活變得無比美好,不是麼?

本文由 SwiftGG 翻譯組翻譯,已經獲得作者翻譯授權,最新文章請通路 http://swift.gg。