Swift 元组到可选赋值
Swift tuple to Optional assignment
我正在 Swift 中编写一些代码来学习这门语言。这是我的基地 class:
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)
编译器说 "Cannot express tuple conversion (Status:Int, Error:String) to (Int?, String?)"
我知道问题是 self.status 和 self.message 是可选的,而 parseResponse 不是 return 可选的(我不希望它是)。我如何告诉它进行必要的分配和转换以将数据放入实例变量?
你必须这样做(不需要选项):
let returnValue = self.parseResponse(resultBody)
(self.status,self.message) = (returnValue.Status,returnValue.Error)
另一个答案建议(在更改之前)只是做:
(self.status!, self.message!) = self.parseResponse(resultBody)
我发现这是不安全的。如果 self.status
或 self.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?
变量。元组分配失败,因为类型需要匹配。
我正在 Swift 中编写一些代码来学习这门语言。这是我的基地 class:
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)
编译器说 "Cannot express tuple conversion (Status:Int, Error:String) to (Int?, String?)"
我知道问题是 self.status 和 self.message 是可选的,而 parseResponse 不是 return 可选的(我不希望它是)。我如何告诉它进行必要的分配和转换以将数据放入实例变量?
你必须这样做(不需要选项):
let returnValue = self.parseResponse(resultBody)
(self.status,self.message) = (returnValue.Status,returnValue.Error)
另一个答案建议(在更改之前)只是做:
(self.status!, self.message!) = self.parseResponse(resultBody)
我发现这是不安全的。如果 self.status
或 self.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?
变量。元组分配失败,因为类型需要匹配。