2015-08-24 62 views
11

我在Swift中編寫一些代碼來學習語言。這裏是我的基類:Swift元組爲可選賦值

import Foundation 
class BaseCommand:NSOperation 
{ 
    var status:Int? = nil 
    var message:String? = nil 

    func buildRequest() -> NSData? 
    { 
     return nil 
    } 

    func parseResponse(data:NSData?) -> (Status:Int, Error:String) 
    { 
     return (200, "Success") 
    } 

    override func main() { 
     let requestBody = self.buildRequest() 

     println("Sending body \(requestBody)") 
     // do network op 
     var networkResultBody = "test" 

     var resultBody:NSData = networkResultBody.dataUsingEncoding(NSUTF8StringEncoding)! 
     (self.status, self.message) = self.parseResponse(resultBody) 
    } 
} 

的問題是最後一行:

(self.status, self.message) = self.parseResponse(resultBody) 

編譯器說:「無法用語言表達的元組轉換(狀態:詮釋,錯誤:字符串)(智力?字符串?)「

我明白,問題是self.status和self.message是可選項,並且parseResponse不會返回可選項(我不希望它)。我如何告訴它執行必要的分配並將其轉換爲實例變量中的數據?

回答

5

另一個答案建議(修改前)只是做:

(self.status!, self.message!) = self.parseResponse(resultBody) 

我發現是不安全的。如果在分配時self.statusself.messagenil,它將會崩潰。試試這個測試在一個遊樂場:

class Test { 
    var status: Int? 
    var error: String? 

    func parseResponse() -> (Status:Int, Error:String) 
    { 
     return (200, "Success") 
    } 

    func testIt() { 
     (self.status!, self.error!) = parseResponse() 
     print(self.status) 
     print(self.error) 
    } 
} 

let mytest = Test() 
mytest.testIt() 

這裏是另一種方式,它可以這樣做:

let (stat, err) = self.parseResponse(resultBody) 
(self.status, self.error) = (Optional(stat), Optional(err)) 

,或者如@AndriyGordiychuk發現,它的工作原理沒有Optional

let (stat, err) = self.parseResponse(resultBody) 
(self.status, self.error) = (stat, err) 

這很有好奇,但是分配函數的結果並沒有。


注意以下實驗:

var i: Int? 
var s: String? 

// This works 
(i, s) = (3, "hello") 

// This fails with error: cannot express tuple conversion '(Int, String)' to '(Int?, String?) 
let t = (3, "hello") 
(i, s) = t 

看來,當分配是一個元組文字分配給一個元組,斯威夫特需要一個快捷方式,不先建立元組。相反,只是分配各個元素。

所以這個:

(i, s) = (3, "hello") 

等同於:

i = 3 
s = "hello" 

它的作品,因爲你可以指定一個IntInt?變量和StringString?變量。元組分配失敗,因爲類型需要匹配。

+0

可以分解元組並重建它 (I,S)=(t.0,T.1) –

3

你要做到這一點(沒有自選需要):

let returnValue = self.parseResponse(resultBody) 
(self.status,self.message) = (returnValue.Status,returnValue.Error) 
+0

如果'self.status'或'self.message'在當時是'nil',你的第一個方法會崩潰。 – vacawama

+0

我測試過了。它不會崩潰。爲什麼呢?如果你打開它們並分配給那些期望非零值的東西,它會崩潰。顯式解開nil本身不會導致崩潰;) –

+0

請參閱我的答案。如果'self.status'或'self.message'爲'nil',我的遊樂場測試會在Xcode 6.4和7.0 beta 5中崩潰。 – vacawama