2015-04-23 27 views
-2

假設下面的代碼:所以,如果字符串不是NilLiteralConvertible ...一些字符串函數返回什麼?

let url = "http://%20abc" 
let urlString = url.stringByRemovingPercentEncoding! 
if urlString != nil { 
    println("done") 
} 

stringByRemovingPercentEncoding應該返回一個可選的字符串。所以讓我們解開它。現在當它真的'失敗'並且不返回字符串時會發生什麼?

字符串不是NilLiteralConvertible,因此下一行有編譯器錯誤。我真的很困惑 - 所以如果我認爲url.stringByRemovingPercentEncoding是一個unwrapped可選項,我應該如何比較urlString?顯然它不適用於零。

請注意我可以將urlString作爲一個可選值,然後解開它等。這不是重點。關鍵是這個確切的案例。非常感謝!

+0

發佈此問題30秒前,得到了一個downvote。小心解釋,親愛的downvoter,爲什麼? – Fygo

+2

我沒有投票,但我猜是因爲你的代碼是一個顯而易見的非序列。根據答案,你隱式地解開可選,然後嘗試並將其視爲可選 – Paulw11

+0

也可能是因爲它不清楚這與'NilLiteralConvertible'有什麼關係,這不是該代碼生成的錯誤。 – nhgrif

回答

3
let url = "http://%20abc" 
let urlString = url.stringByRemovingPercentEncoding! 
if urlString != nil { 
    println("done") 
} 

的錯誤我得到的有在!=,在那裏說:

Binary operator != cannot be applied to operands of the type String and nil

這是合理的。爲什麼我們甚至要想要使用Stringnil之間的任何比較運算符。 A String不能nil

現在,url.stringByRemovingPercentEncodingString?返回類型,但是我們使用的是隱式展開可選的,這意味着urlString要麼是String,並有一個值,否則我們會得到一個致命錯誤(意外地發現nil展開一個可選項)。

如果我們刪除我們的隱含展開操作:

let url = "http://%20abc" 
let urlString = url.stringByRemovingPercentEncoding 
if urlString != nil { 
    println("done") 
} 

現在的代碼是非常幸福的。我們的變量urlString現在不是String,而是String?。我們可以使用!=來比較任何可選項與nil,因爲可選項可以不爲

但也許寫這個最SWIFTY方式是這樣的:

let url = "http://%20abc" 
if let urlString = url.stringByRemovingPercentEncoding { 
    // do something with urlString 
    println("done") 
} 

在這種情況下,urlStringString類型的,所以我們沒有解開它,但if塊只有當url.stringByRemovingPercentEncoding返回非零時,纔會進入(並且我們只能在if塊內使用urlString)。


並記錄在案,如果我們不是真的要做到與urlString什麼,我們有以下兩種選擇:

if url.stringByRemovingPercentEncoding != nil { 
    println("done") 
} 

也:

if let _ = url.stringByRemovingPercentEncoding { 
    println("done") 
} 
+0

哦,我明白了。我知道它爲什麼會發生,我只是不太明白,爲什麼它不能被隱式地解開。我可以只是把* let urlString:String!*我假定編譯器實際上已經指出了這一點。謝謝你的幫助! – Fygo

+3

用'!'特別小心地踩踏。我強烈建議你不要使用它,除非你真的*知道你在做什麼。你會不斷遇到「致命的錯誤:意外地發現零,同時解開可選的」問題。 – nhgrif

相關問題