想當初剛在學習JAVA時
一段 new String("ami") != new String("ami")
輸出結果是false
搞得一個程式小萌新坐在教室裡一臉矇
導致現在的我每次在學習一個新語言時
都會特別多看一點字串操作方面的文件
接下來一起研究一下字串吧!
// 字串宣告
let name = "swift"
// 字串連接
let welString1 = "Welcome, " + name + "!"
print(welString1) // 輸出: Welcome, swift!
// 字串插值
let welString2 = "Welcome, \(name)!"
print(welString2) // 輸出: Welcome, swift!
// 字串賦值與修改
var welString3 = welString2
welString3 += " Have a nice time!"
print(welString3) // 輸出: Welcome, swift! Have a nice time!
// 字串直接比對值
print(welString2 == "Welcome, swift!") // 輸出: true
// 字串比對 實際上是比對 Unicode值
print("é" == "e\u{301}") // 輸出: true
// 擷取字串元素 取字串 直到第一個空白為止
let myName = "Ami Wu"
print( myName.split(separator: " ")[0]) // 輸出: Ami
// 取字串數量
print(myName.count) // 輸出: 6
// 字串轉陣列
print(Array(myName)) // 輸出: ["A", "m", "i", " ", "W", "u"]
// 新增字串
var newName = "new"
newName.append(" day")
print(newName) // 輸出: new day
// 大小寫轉換
print("ami Test".lowercased()) // 輸出: ami test
print("ami Test".uppercased()) // 輸出: AMI TEST
// 判斷字串
print("ami test".hasPrefix("ami")) // 前綴 輸出: true
print("ami test".hasSuffix("test")) // 後綴 輸出: true
print("ami test".contains("te")) // 包含 輸出: true
// 多行文字模板
let s1 = """
這邊可以多行輸入
很方便喔
"""
print(s1)
//輸出:
//這邊可以多行輸入
// 很方便喔
字串操作上蠻直覺的
只是 \()
這種插值法 蠻特別的
多行模板操作起來也很方便
fun main() {
// 字串宣告
val name = "kotlin"
// 字串連接
val welString1 = "Welcome, " + name + "!"
println(welString1) // 輸出: Welcome, kotlin!
// 字串插值
val welString2 = "Welcome, $name!"
println(welString2) // 輸出: Welcome, kotlin!
// 字串賦值與修改
var welString3 = welString2
welString3 += " Have a nice time!"
println(welString3) // 輸出: Welcome, kotlin! Have a nice time!
// 字串直接比對值
println(welString2 == "Welcome, kotlin!") // 輸出: true
// 字串比對 實際上是比對 Unicode值
println("é" == "e\u0301") // 輸出: false "é" 與 "é" 實際上比對會不相等
// 訪問字串元素 取字串 直到第一個空白為止
var myName = "Ami Wu"
println(myName.split(' ')[0]) // 輸出: Ami
// 取字串數量
println(myName.length) //6
// 字串轉陣列
println(myName.toList()) // 輸出: [A, m, i, , W, u]
// 新增字串
var newName = "new"
println(newName.plus(" day")) // 輸出: new day
println(newName) //並不會直接改變 // 輸出: new
// 大小寫轉換
println("ami Test".lowercase()) // 輸出: ami test
println("ami Test".uppercase()) // 輸出: AMI TEST
// 判斷字串
println("ami test".startsWith("ami")) // 判斷起始 輸出: true
println("ami test".endsWith("test")) // 判斷結尾 輸出: true
println("ami test".contains("te")) // 包含 輸出: true
// 多行文字模板 他會連前方空白一起加入
var s1 = """
這邊可以多行輸入
很方便喔
"""
print(s1)
// 輸出:
// 這邊可以多行輸入
// 很方便喔
}
kotlin 在字串操作上 與swift只有用字上稍微不同
其他大部分都相同
但 "é" != "é" 這件事情...倒是讓人有點困惑
不是困惑為什麼不能相等.... 而是Swift為什麼相等了?
今天阿咪我困惑啊
é != é
是我眼睛業障重嗎?
文字看起來一樣
但JS的 charAt 一個是101 一個是 233
Unicode 一個是 %E9 一個是 e%u0301
除了Swift之外 其他語言判斷起來都不相等
連用equals判斷也不相等 ლ(゚д゚ლ)
你說說我容易嗎
看著官方Swift的文件練習一下
就卡關!?
我還拿著這題去問寫iOS APP的朋友
他們回我...這題太深入了 沒研究
這顆大蘋果啊~你的開發文件水很深啊
有沒有Swift大神可以指教一下
這到底是什麼道理~
我看了一下官方文件第114頁是這樣寫
「Two String values (or two Character values) are considered equal if their extended grapheme clusters are canonically equivalent. Extended grapheme clusters are canonically equivalent if they have the same linguistic meaning and appearance, even if they’re composed from different Unicode scalars behind the scenes.」
給谷狗大神翻譯一下
「如果兩個 String 值(或兩個 Character 值)的擴展字素簇在規範上等效,則認為它們相等。 如果擴展的字素簇具有相同的語言意義和外觀,則它們在規範上是等效的,即使它們在幕後由不同的 Unicode 標量組成。”
結論
只要是同一個字(相同的語言意義和外觀),不管背後是不是用組的,都會是相等的
WOW~~~~~~~~ 太神啦
看起來Swift在判斷上
更“真實”一點
其他語言還是建構在判斷Unicode上。
感謝您的解答!