Optional变量初学者指南

苹果三周前发布了Swift。 从那时起,我一直在阅读Swift的官方指南,并在Xcode 6测试版中使用。 我开始喜欢Swift的简单和语法。 与我的团队一起,我仍然在研究新的语言,并看看它与Objective-C(一种30岁的编程语言)相比如何。 同时,我们正在努力工作,看看我们如何教初学者,帮助社区轻松应对Swift。

两周前,我们介绍了Swift的基础知识。 在接下来的几周内,我们将编写一系列教程,以涵盖Swift中的许多新功能。 本周,我们先来看看Optional变量。

Optionals 概览

我在上一篇文章中提到了可选项,但没有详细介绍。 那么什么是可选项? 在Swift中声明变量时,默认情况下它们被指定为非可选项。 换句话说,您必须为变量分配非空值。 如果您尝试将一个零值设置为非可选项,编译器会说:“你不能设置一个空值!”。

var message: String = "Swift is awesome!" // OK
message = nil // compile-time error

当然,错误消息不是那么用户友好,但它类似“__conversion’ that accepts the supplied arguments“。 同样适用于在类中声明属性时。 默认情况下,属性被指定为非可选属性。

class Messenger {
    var message1: String = "Swift is awesome!" // OK
    var message2: String // compile-time error
}

您将收到message2的编译时错误,因为它没有分配初始值。 对于来自Objective-C的用户,可能会有点惊讶。 在Objective-C中,在将nil分配给变量或声明没有初始值的属性时,不会得到任何编译时错误:

NSString *message = @"Objective-C will never die!";
message = nil;

class Messenger {
    NSString *message1 = @"Objective will never die!";
    NSString *message2;
}

但是,这并不意味着您无法在Swift中分配初始值时声明属性。 Swift引入了可选类型来表示没有值。 它是通过添加问号来定义的? 运算符类型声明后。 这是一个例子:

class Messenger {
    var message1: String = "Swift is awesome!" // OK
    var message2: String? // OK
}

当变量被定义为可选时,仍然可以赋值。 但是,如果变量象上面的代码一样没有分配任何值,其值将自动默认为nil。

为什么要用 Optionals?

 Swift是为安全而设计的。 正如苹果所说,可选项是Swift是一种类型的安全语言的例子。 从上面的例子可以看出,Swift的可选项提供编译时检查,可以防止在运行时发生一些常见的编程错误。 我们来看下面的例子,你将更好地了解可选项的功能。

在Objective-C中考虑以下方法:

- (NSString *)findStockCode:(NSString *)company {
    if ([company isEqualToString:@"Apple"]) {
        return @"AAPL";
    } else if ([company isEqualToString:@"Google"]) {
        return @"GOOG";
    }
    return nil;
}

您可以使用findStockCode:方法获取特定上市公司的股票代码。 为了演示目的,该方法只返回您的Apple和Google的股票代码。 对于其他输入,它返回空值。

假设该方法在同一个类中定义,我们使用它:

NSString *stockCode = [self findStockCode:@"Facebook"]; // nil is returned
NSString *text = @"Stock Code - ";
NSString *message = [text stringByAppendingString:stockCode]; // runtime error
NSLog(@"%@", message);

该代码可以正确编译,但是当该方法对Facebook返回nil时,运行该应用程序会抛出运行时异常。

使用Swift的可选项,它会在编译时显示错误,而不是在运行时发现错误。 如果我们在Swift中重写上述示例,它将如下所示:

func findStockCode(company: String) -> String? {
   if (company == "Apple") {
      return "AAPL"
   } else if (company == "Google") {
      return "GOOG"
   }
   return nil
}
 
var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
let message = text + stockCode  // compile-time error
println(message)

stockCode被定义为可选项。 这意味着它可以包含字符串或空值。 您无法执行上述代码,因为编译器检测到潜在错误(“可选类型String的值未展开”),并通知您进行更正。

从示例中可以看出,Swift的可选功能加强了空值检查,为开发人员提供了编译时的指引。 显然,使用可选项有助于更好的代码质量。

可选变量解包

那么我们该如何使代码工作? 显然,我们需要测试stockCode是否包含一个空值。 我们修改如下:

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
if stockCode {
    let message = text + stockCode!
    println(message)
}

就像Objective-C对应的,我们使用if来查看可选项是否包含一个值。 一旦我们知道可选项必须包含一个值,我们通过在可选名称的末尾放置一个感叹号(!)来解开它。 在Swift,这被称为强制展开。 你用! 操作符打开可选项并显示底层值。

参考上面的例子,我们只在nil-check之后解开“stockCode”可选项。 我们知道可选量必须包含非零值,然后才能使用! 操作符。 始终建议确保可选项在解开之前包含一个值。

但是如果我们忘记下面的验证怎么办?

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
let message = text + stockCode!  // runtime error

将不会有编译时错误。 编译器假定可选的包含一个值,因为使用了强制展开。 运行应用程序时,将抛出运行时错误,并显示以下消息:

fatal error: Can’t unwrap Optional.None
可选绑定

除了强制解包之外,可选绑定是一种更简单和推荐的方式来打开可选的。 您使用可选绑定来检查可选项是否包含值。 如果它包含一个值,将其解开并将其放入临时常量或变量中。

没有比使用示例更好的解释可选绑定的方式。 我们将上一个示例中的示例代码转换为可选绑定:

var stockCode:String? = findStockCode("Facebook")
let text = "Stock Code - "
if let tempStockCode = stockCode {
    let message = text + tempStockCode
    println(message)
}

“if let”(或“if var”)是可选绑定的两个关键字。 通俗地,代码说“如果stockCode包含一个值,将其解开,将其值设置为tempStockCode并执行条件块。 否则,只是跳过块“。 由于tempStockCode是一个新的常量,您不再需要使用! 后缀访问其值。

您可以通过评估if语句中的函数来进一步简化代码:

let text = "Stock Code - "
if var stockCode = findStockCode("Apple") {
    let message = text + stockCode
    println(message)
}

这里的stockCode不是可选的,没有必要使用! 后缀访问条件块中的值。 如果从函数返回nil值,则不会执行该块。

可选链

在解释可选链接之前,让我们稍微调整一下原来的例子。 我们创建一个名为Stock的新类,其代码和价格属性是可选的。 findStockCode函数被修改为返回Stock类而不是String。

class Stock {
    var code: String? 
    var price: Double? 
}
 
func findStockCode(company: String) -> Stock? {
    if (company == "Apple") {
        let aapl: Stock = Stock()
        aapl.code = "AAPL"
        aapl.price = 90.32
 
        return aapl
            
    } else if (company == "Google") {
        let goog: Stock = Stock()
        goog.code = "GOOG"
        goog.price = 556.36
            
        return goog
    }
        
    return nil
}

我们重写原始示例如下。 我们首先通过调用findStockCode函数找到股票代码/符号。 然后我们计算购买100股股票所需的总成本。

if let stock = findStockCode("Apple") {
    if let sharePrice = stock.price {
        let totalCost = sharePrice * 100
        println(totalCost)
    }
}

由于findStockCode()的返回值是可选的,我们使用可选绑定来检查它是否包含实际值。 显然,股票类的价格属性是可选的。 我们再次使用“if let”语句来测试stock.price是否包含非零值。

上述代码没有任何错误。 您可以使用可选链接来简化代码,而不是编写嵌套的“if set”。 该功能允许我们连接多个可选项与“?”操作符。 这是代码的简化版本:

if let sharePrice = findStockCode("Apple")?.price {
    let totalCost = sharePrice * 100
    println(totalCost)
}

可选链接提供了访问价格价值的另一种方法。 该代码现在看起来更清洁和更简单。 这里我只是介绍可选链接的基础知识。 您可以在Apple Swift指南中找到有关可选链接的更多信息。

Swift和Objective-C互操作性

Swift的可选功能非常强大,尽管可能需要一些时间来习惯语法。 可选项可以帮助您清楚代码可以使用的值,并避免错过无效。

Swift旨在与Objective-C API进行交互。 每当您需要与UIKit或其他框架API进行交互时,您一定会遇到可选项。 以下是实现表视图时遇到的一些可选项:

func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
        // Return the number of sections.
        return 1
    }
 
    func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
        // Return the number of rows in the section.
        return recipes.count
    }
    
 
    func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        
        cell.textLabel.text = recipes[indexPath.row]
        
        return cell
    }

概要

了解可选项如何工作至关重要,这就是为什么我们将完整的文章用于可选项。 Swift中的可选项允许开发人员在编译时发现潜在的问题,从而在运行时防止意外的错误。 一旦你习惯了语法,你会欣赏可选的美丽。

和往常一样,我们很乐意听到您的反馈。 如果您对可选项有任何疑问或想分享您的想法,请随时给我们留言。

转载于:https://www.cnblogs.com/luoxs/p/6678828.html

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
应用背景为变电站电力巡检,基于YOLO v4算法模型对常见电力巡检目标进行检测,并充分利用Ascend310提供的DVPP等硬件支持能力来完成流媒体的传输、处理等任务,并对系统性能做出一定的优化。.zip深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值