Swift 3在初始化类后获取选项

时间:2017-03-03 02:26:31

标签: swift

我有以下名为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中运行良好

2 个答案:

答案 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的类型是什么?是IntImplicitlyUnwrappedOptional<Int>(又名Int!)还是Optional<Int>(又名Int?)?事实证明,在Swift 2中,x1Int?类型。你必须成为语言大师才能知道这一点。

您可以在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?,而不是隐式解包它。