Swift Failable Initializers - 无法使我的代码正常工作

时间:2017-01-11 07:48:55

标签: ios swift initialization optional

我很难理解为什么我的代码无效?任何帮助/纠正表示赞赏。

struct DogBowlWithFailableInitializers {
    var foodLeft: Int
    init?(foodLeft: Int) {
        if foodLeft < 0 {
            return nil
        }
        self.foodLeft = foodLeft
    }
}

if let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10) {
    print("Success!")
    let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10)
}
else {
    print("Invalid dog food amount inputted")
}

根据我的理解,应该创建一个新实例,因为它在结构内部和外部都传递了if语句。但是当我尝试访问实例中的任何属性时,我无法,为什么会这样?

print(negativeDogFoodTest.foodLeft) //doesn't work

2 个答案:

答案 0 :(得分:0)

negativeDogFoodTest是一个局部变量,其范围位于then - if的分支中。它不存在于该块之外。

所以你需要这样做:

if let negativeDogFoodTest = ... {
    print(negativeDogFoodTest.foodLeft)
}

请注意,您对negativeDogFoodTest的第二次分配是多余的。

您也可以使用guard代替:

guard let negativeDogFoodTest = ... else {
    dealWithFailure()
    (return|break|continue)
}

print(negativeDogFoodTest.foodLeft)

答案 1 :(得分:0)

您似乎无法理解范围的概念。考虑这个简单的if if语句:

if let x = y {
    // A
    someVariable = x // works
}
// B
someVariable = x // does not work

x只能在if语句中访问,即A。在if语句之外,即在Bx 超出范围

为什么呢?因为在x访问B没有任何意义,因为无论B是否为零,都会执行y

所以你应该在if语句中访问它。

另一个问题是您声明negativeDogFoodTest两次:

// 1st time
if let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10) {
    print("Success!")
    // 2nd time!
    let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10)
}

一次就足够了!

if let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10) {
    print("Success!")
    print(negativeDogFoodTest.foodleft)
}

您还可以考虑一份警卫声明:

guard let negativeDogFoodTest = DogBowlWithFailableInitializers(foodLeft: 10) 
    else { return }