我有以下名为User
class User: CustomStringConvertible {
var id: Int!
var firstName: String!
var lastName: String!
init(){
}
init(id: Int, firstName: String, lastName: String) {
self.id = id
self.firstName = firstName
self.lastName = lastName
}
var description: String{
return "id = \(id); first name = \(firstName); last name = \(lastName)"
}
}
然后我用以下代码调用该类:
let user = User(id: userData["id"] as! Int, firstName: userData["first_name"] as! String, lastName: userData["last_name"] as! String)
致电print(user)
后,我收到以下信息:
id = Optional(1); first name = Optional("John"); last name = Optional("Doe")
当我的变量由Optional(1)
定义时,为什么打印Optional("John")
,Type!
。我知道答案可能很简单,但我无法弄清楚。它在Swift 2.0中运行良好
答案 0 :(得分:1)
将init构造函数更改为类似
的内容init(id: Int!, firstName: String!, lastName: String!) {
self.id = id
self.firstName = firstName
self.lastName = lastName
}
使用guard-if
语句获取值
guard if let userID = userData["id"] as? Int, ..... else{
return
}
然后使用这些值初始化User
对象。
答案 1 :(得分:1)
在Swift 2中,Int!
类型是ImplicitlyUnwrappedOptional<Int>
的简写。编译器特别处理了ImplicitlyUnwrappedOptional
:它可以在允许Optional
的上下文中被视为Optional
,并且在不允许Optional
的上下文中自动(隐式)展开
问题在于,很难理解编译器在各种情况下对Int!
的作用。以下是众多例子中的一个:
func f() -> Int! { return 3 }
let x1 = f()
Swift 2中该代码中x1
的类型是什么?是Int
,ImplicitlyUnwrappedOptional<Int>
(又名Int!
)还是Optional<Int>
(又名Int?
)?事实证明,在Swift 2中,x1
是Int?
类型。你必须成为语言大师才能知道这一点。
您可以在this swift-evolution thread中找到更多关于取消ImplicitlyUnwrappedOptional
类型的示例。
对于Swift 3,Swift团队采用了SE-0054: Abolish ImplicitlyUnwrappedOptional
type。 SE-0054完全删除了ImplicitlyUnwrappedOptional
类型,并更改了var id: Int!
的含义。现在它声明id
的类型为Optional<Int>
,但如果您使用id
仅,则接受普通Int
,则编译器会隐式解包它适合你。 在所有其他情境中,id
被视为Int?
(又名Optional<Int>
)。只要编译器可以将id
视为Int?
,它就会这样做。
这就是为什么Swift 2和Swift 3之间的结果不同的原因。在Swift 2中,编译器会隐式地将id
(以及其他属性)展开到比Swift 3更多的位置。自字符串插值("\(...)"
)可以接受任何类型,Swift 3编译器将id
传递为Int?
,而不是隐式解包它。