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)

编译器说"不能表示元组转换(状态:Int,错误:String)到(Int?,字符串?)"

我明白问题是自我。状态和自我。消息是可选的,并且parserresponse不返回optional(我也不希望它返回)。我如何告诉它做必要的分配和转换,以获得数据到实例变量?

另一个答案建议(在更改之前)只做:

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

我发现那是不安全的。如果self.statusself.message在分配时是nil,它将崩溃。在Playground中试试这个测试:

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

看起来,当赋值是一个元组文字赋值给一个元组时,Swift会走捷径,不会先构造这个元组。相反,它只是赋值单个元素。

:

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

等价于:

i = 3
s = "hello"

可以工作,因为您可以将Int分配给Int?变量,将String分配给String?变量。元组赋值失败,因为类型需要匹配。

你必须这样做(不需要可选):

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

最新更新