我試圖將一個Swift腳本移植到Kotlin,但它不像預期的那樣工作,代碼所做的就是在條件爲真(需要解析器)時使用字符串。在Swift中,它按預期工作,但在Kotlin中它沒有(我剛剛在一個月前開始使用Kotlin,所以也許我錯過了一些東西)。從一個擴展名中突變字符串
斯威夫特
extension String {
@discardableResult public mutating func consumeWhile(test: (String) -> Bool) -> String {
var chars = [Character](self.characters)
var result = ""
while chars.count > 0 && test(String(chars[0])) {
result.append(chars.remove(at: 0))
}
self = String(chars)
return result
}
}
科特林
fun String.consumeWhile(test: (String) -> Boolean): String {
if (isEmpty()) return ""
val chars = toCharArray().toMutableList()
var result = ""
var i = -1
while (chars.isNotEmpty() && test(chars.first().toString())) {
result += chars.removeAt(0)
++i
}
removeRange(0..i)
return result
}
所以基本用法看起來像
val myString = "--Test" // IntelliJ suggests change var to val
val consumedString = myString.consumeWhile{ it != "-" }
println("result: $myString consumedString: $consumedString")
// expected: "result: Test consumedString: --"
// but got: "result: --Test consumedString: --"
編輯:感謝所有的答案,不知道是否可以像我想要的那樣做,因爲所提到的字符串在Kotlin/Java中是不可變的(只是使用相同的字符串)。
我忘了提,我需要消耗的字符串,基本上B/C我做一個解析器,所以我需要存儲的消耗字符和字符串突變。我將留下這個問題,但我最終創建了一個只實現了幾個String類方法的類。
class Line(var string: String) {
val length: Int
get() = string.length
fun consumeWhile(test: (String) -> Boolean): String {
if (string.isEmpty()) return ""
val chars = string.toCharArray().toMutableList()
var result = ""
while (chars.isNotEmpty() && test(chars.first().toString())) {
result += chars.removeAt(0)
}
string = chars.joinToString("")
return result
}
fun isNullOrEmpty(): Boolean {
return string.isNullOrEmpty()
}
fun isNotEmpty(): Boolean {
return string.isNotEmpty()
}
private fun removeRange(range: IntRange) {
string = string.removeRange(range)
}
operator fun get(i: Int): Char {
return string[i]
}
}
使用例如
val line = Line(string)
if (line.isNotEmpty() && line[0].toString() == "(") {
line.consumeWhile { it == "(" }
while (line.isNotEmpty() && line[0].toString() != ")") {
line.consumeWhile { it == " " }
val key = line.consumeWhile { it != "=" }
line.consumeWhile { it == "\"" || it == "=" }
val value = line.consumeWhile { it != "\"" }
line.consumeWhile { it == "\"" }
attributes[key] = value
}
line.consumeWhile { it == ")" }
}
這似乎有趣,我已經沒想到那種方法,會嘗試一下。還請查看我更新的問題,並附上一些進一步的解釋。 – norman784
雖然有效,但結果有點難看,現在您無法將元組/對輸出分配到現有變量中,您需要將返回值分配給新變量,即:val string =「Test」; val(_,newString)= string.consumeWhile {...}; val(_,newString2)= newString.consumeWhile {...}; – norman784