Swift: 许多内置函数 return 可选类型。如何在没有丑陋的嵌套 ifs 的情况下将它们变成常规变量?

Swift: many built-in functions return Optional types. How can I turn them into regular variables without ugly nested ifs?

TL;博士?请给我一个例子,说明如何处理可能 return 一个字符串并且可能 return nil 的字符串初始化方法,没有:1)将它分配给一个可选的字符串变量,2)使用丑陋的嵌套循环来处理 nil/non-nil 个案例,或者 3) 假设它永远不会为 ! 的 nil,当它很可能为 nil 并且那会杀死我的应用程序时。

我正在学习 Swift,并尝试发送 REST 请求。这是我写的开头代码:

    let restCallStr = String(format:"%@connect/token", arguments:[BASE_REST_URL]);
    restCallStr = restCallStr.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet());
    let restURL = NSURL(string:restCallStr);
    var restRequest = NSMutableURLRequest(URL:restURL);
    restRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type");
    restRequest.HTTPMethod = "POST";
    let completionClosure: (response:NSURLResponse!, data:NSData!, error:NSError!) -> () = {
        var jsonDict:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error:nil) as NSDictionary;
        println("Response: \(jsonDict)");
    };
    NSURLConnection.sendAsynchronousRequest(restRequest, queue: NSOperationQueue(), completionHandler:completionClosure);

看起来与我在 Objective-C 中所做的非常相似,并且看起来应该可以工作...

但事实并非如此。我正在调用的所有内置 init 方法(String(format:"", arguments:[])NSURL(string:"") 等)都不会 return 常规字符串或 NSURL 变量...它们 return 可选。

现在我已经研究了可选项,并且我相信我了解它们如何工作的基础知识。我正在苦苦挣扎的是如何实际处理它们(并且到处都没有大量丑陋的多余代码)。

网络上的建议似乎是 "just use ! to cast it out of the optional"(反对者争论 "Noooooo, you should (almost) never use !!",常识告诉我 ! 在这里没有意义,因为如果值是零我需要处理它,而不仅仅是崩溃)。

似乎能够真正处理 nil 和非 nil 情况的唯一解决方案似乎是 if let,所以我决定试一试。仅修改了我的原始代码的 2 行,我就已经开始了一个丑陋的嵌套 if 语句树:

    let restURLStr = String(format:"%@connect/token", arguments:[BASE_REST_URL]);
    if let encodedRestURLStr = restURLStr.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
    {
        if let restURL = NSURL(string:encodedRestURLStr)
        {
            var restRequest = NSMutableURLRequest(URL:restURL);
            restRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type");
            restRequest.HTTPMethod = "POST";
            let completionClosure: (response:NSURLResponse!, data:NSData!, error:NSError!) -> () = {
                var jsonDict:NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error:nil) as NSDictionary;
                println("Response: \(jsonDict)");
            };
            NSURLConnection.sendAsynchronousRequest(restRequest, queue: NSOperationQueue(), completionHandler:completionClosure);
        }
        else
        {
            println("Oops, nil assigned to restURL! Better handle that.");
        }
    }
    else
    {
        println("Oops, nil assigned to restCallStr! Better handle that.");
    }

我已经很头疼了,只是想象如果我必须每次都这样做会是什么样子(以及会导致多少浪费的击键)每一次我做一个可能为零的赋值。

更好的方法。 Swift 做了很多漂亮的事情,但现在我渴望一大块好的 ol' obj-c 代码,我不需要无数的嵌套语句来处理完全可接受的 nil 值。

伙计们,解决这个问题的方法是什么?大家都在说Swift怎么这么精简,这么牛逼,这种事情怎么可能这么处理。

因此他们添加了一种使用 guard let 安全解包的新方法。您可以在此示例中的外部使用 myUrl,因此无需再使用 if 进行嵌套。例如:

   guard let myUrl = NSURL(string:"www.myWebsite.com") else {
   return
   }