Swift:为什么我仍然需要可选值?
Swift: why do I need optionals anyways?
我已经阅读了几篇有关它的文章并理解了基本原理,并且同意它在某些情况下可能会有用。但是,大多数情况下,如果我 nil
到了我不应该去的地方,我会希望我的程序崩溃——这就是我怎么知道有问题的!
此外,我读到使用可选值可以缩短代码。这怎么可能??据我所见,它们背后的整个想法是它们可以有一个值或 nil
所以你必须做额外的检查,而以前这是没有必要的!
需要一直使用 "as" 是怎么回事?它只会让一切变得更加冗长和冗长。比如比较下面的代码在Objective-C和Swift
Objective-C:
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Home"];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = vc;
[UIView transitionWithView:appDelegate.window
duration:0.2
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{ appDelegate.window.rootViewController = vc; }
completion:nil];
Swift:
//have to check if self.storyboard != nil
let viewController:UIViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Home") as UIViewController; //Isn't the view controller returned by instantiateViewControllerWithIdentifier() already of type UIViewController?
let appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate; //Isn't the delegate returned by sharedApplication() already of type AppDelegate?
//have to check if appDelegate.window != nil
appDelegate.window!.rootViewController = viewController as UIViewController; //Why cast viewController as UIViewController if the type has already been explicitly set above?
UIView.transitionWithView(
appDelegate.window!,
duration: 0.2,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations:{appDelegate.window!.rootViewController = viewController as UIViewController},
completion: nil
);
我做错了什么吗?或者这真的是它想要的样子吗?
可选
如果你确定一个变量应该 永远不会 为 nil,你可以使用 !
强制解包一个可选的或使用 [=12= 声明为隐式解包].当它为 nil 时,这将导致崩溃,就像你想要的那样。
但是,对于某些变量,将它们设置为零是合理的。例如,User
模型的 age
变量未设置,因为用户未提供它。
明确将它们标记为可选并使用 if let
展开它们会迫使您考虑可空性。最后,这会创建更健壮的代码。
我不认为它会导致代码短路。在 Objective-C 中使用 if var != nil
的地方在 Swift 中使用 if let var = var
。在 Obj-C 中向 nil 发送消息是一个 noop,您可以在 Swift 中使用 var?.method()
获得相同的行为。最后还是一样。
铸造(as)
你现在需要在 Swift 中强制转换的一个重要原因是因为一些 Objective-C 方法 return id
,这在 Obj-C 中没有问题但会导致麻烦在 Swift。我希望随着 Swift 变得越来越流行并且框架得到调整,这种情况会减少。
更新代码
我快速查看了您的代码,看来您不需要一半的转换。这是我的想法:
if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("Home") as? UIViewController {
if let window = UIApplication.sharedApplication().delegate?.window {
window.rootViewController = viewController
UIView.transitionWithView(window, duration: 0.2, options: .TransitionCrossDissolve, animations: {
window.rootViewController = viewController
}, completion: nil);
}
}
我已经阅读了几篇有关它的文章并理解了基本原理,并且同意它在某些情况下可能会有用。但是,大多数情况下,如果我 nil
到了我不应该去的地方,我会希望我的程序崩溃——这就是我怎么知道有问题的!
此外,我读到使用可选值可以缩短代码。这怎么可能??据我所见,它们背后的整个想法是它们可以有一个值或 nil
所以你必须做额外的检查,而以前这是没有必要的!
需要一直使用 "as" 是怎么回事?它只会让一切变得更加冗长和冗长。比如比较下面的代码在Objective-C和Swift
Objective-C:
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"Home"];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.window.rootViewController = vc;
[UIView transitionWithView:appDelegate.window
duration:0.2
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{ appDelegate.window.rootViewController = vc; }
completion:nil];
Swift:
//have to check if self.storyboard != nil
let viewController:UIViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Home") as UIViewController; //Isn't the view controller returned by instantiateViewControllerWithIdentifier() already of type UIViewController?
let appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate; //Isn't the delegate returned by sharedApplication() already of type AppDelegate?
//have to check if appDelegate.window != nil
appDelegate.window!.rootViewController = viewController as UIViewController; //Why cast viewController as UIViewController if the type has already been explicitly set above?
UIView.transitionWithView(
appDelegate.window!,
duration: 0.2,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations:{appDelegate.window!.rootViewController = viewController as UIViewController},
completion: nil
);
我做错了什么吗?或者这真的是它想要的样子吗?
可选
如果你确定一个变量应该 永远不会 为 nil,你可以使用 !
强制解包一个可选的或使用 [=12= 声明为隐式解包].当它为 nil 时,这将导致崩溃,就像你想要的那样。
但是,对于某些变量,将它们设置为零是合理的。例如,User
模型的 age
变量未设置,因为用户未提供它。
明确将它们标记为可选并使用 if let
展开它们会迫使您考虑可空性。最后,这会创建更健壮的代码。
我不认为它会导致代码短路。在 Objective-C 中使用 if var != nil
的地方在 Swift 中使用 if let var = var
。在 Obj-C 中向 nil 发送消息是一个 noop,您可以在 Swift 中使用 var?.method()
获得相同的行为。最后还是一样。
铸造(as)
你现在需要在 Swift 中强制转换的一个重要原因是因为一些 Objective-C 方法 return id
,这在 Obj-C 中没有问题但会导致麻烦在 Swift。我希望随着 Swift 变得越来越流行并且框架得到调整,这种情况会减少。
更新代码
我快速查看了您的代码,看来您不需要一半的转换。这是我的想法:
if let viewController = self.storyboard?.instantiateViewControllerWithIdentifier("Home") as? UIViewController {
if let window = UIApplication.sharedApplication().delegate?.window {
window.rootViewController = viewController
UIView.transitionWithView(window, duration: 0.2, options: .TransitionCrossDissolve, animations: {
window.rootViewController = viewController
}, completion: nil);
}
}