Swift 3.0.2 报错:"Type 'bool' is broken"

4
我正在使用这个结构并使用它。
struct Ride {
  var isRideForNow: Bool!    
}
 var sheduleRide: Ride?
 sheduleRide = Ride()
 sheduleRide?.isRideForNow = false

当我像这样使用时,它运行良好。
 if (sheduleRide?.isRideForNow)! {
   //some code
 }

但是我不知道为什么下面的代码会出现错误"Type 'bool' is broken",即使其中没有可选链

 if (sheduleRide!.isRideForNow) {
   //some code
 }

预定乘车是可选的,我猜第一个选项可以使用,而不是第二个。 - Tushar Sharma
1
请在Swift 3.1上编译。 - SuryaKantSharma
完成,请查看。 - SuryaKantSharma
1
@SuryaKantSharma 谢谢 - 然而在Swift 3.1中它仍然可以编译通过(请自行查看)。有趣的是,它在Swift版本3.0-3.0.2中无法编译。您确定您正在运行Swift 3.1吗? - Hamish
1
@vacawama 是的 - 无论如何,OP的代码现在在Swift 3.1中运行良好。它已经在这里作为错误报告,并在此拉取请求中进行了修复。我想我们其中之一应该写一个答案... :) - Hamish
显示剩余5条评论
2个回答

6
这是一个无用的错误信息,只出现在Swift版本3.0到3.0.2中。问题在于Swift没有隐式地解包可选项,因为它认为你正在尝试进行可选项检查。
因此,解决方案就是像@vacawama所说的那样,简单明了地显式解包可选项:
if sheduleRide!.isRideForNow! {
    // some code
}

(当然,如果sheduleRideisRideForNow有一个是nil,则会崩溃)。

然而,在我的看法中,Swift在这里没有隐式解包IUO的事实不符合SE-0054中详细介绍的IUO行为——在可以将其作为强可选项进行类型检查时,应将其视为强可选项,但在其他情况下应隐式解包。

在布尔条件中,编译器无法将表达式作为强可选类型进行类型检查,因此实际上它应该被隐式解包。这种行为已经报告为错误并且在此拉取请求中进行了修复,因此语句如下:

if sheduleRide!.isRideForNow {
    // some code
}

现在在Swift 3.1中可以正常编译。

但是,正如@vadian所说的那样,你应该考虑isRideForNow是否应该是一个IUO。只有当它需要延迟初始化(而且不能使用lazy)时,才应该将其设置为IUO。

如果您在初始化时给它一个值,则可以将其设置为非可选:

struct Ride {
    var isRideForNow: Bool
}

var sheduleRide = Ride(isRideForNow: false)

1
这里有很多内容,包括当恐龙漫游地球时,可以使用 if myOptionalVar { // not nil } 检查可选项是否为 nil,但当变量是 Bool?Bool! 时会引起混淆。 - vacawama
1
@vacawama确实,那真的是从(Obj-)C行为中测试nil / NULL的遗留问题,我很高兴它被移除了。我认为为了最小惊奇原则,在if语句中使用Bool! / Bool?表达式的当前(Swift 3.1)行为是正确的。虽然对于完全没有惊喜的体验,尽可能避免使用IUO是一个好方法 :) - Hamish
1
“宿醉”这个词比“保持”的用法更合适 :-)。我完全同意尽可能避免使用非空可选类型。 - vacawama

0

在编程中,使用explicitlyVar!是我解决问题的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接