- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Swift中非可选的可选值类型处理方法详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
在我们使用objective-c表示字符串信息的时候,可以用下面方法书写.
1
2
|
NSString *str = @
"秋恨雪"
;
str = nil;
|
因为objective-c是弱类型语言,所以这里的str既可以是具体的字符串也可以是nil。但到了Swift中就不可以了,因为Swift是类型安全的语言,一个String类型的变量不可能既能是具体的字符串,又可以为nil(更严格的说String类型的内容只能是字符串)。所以,在Swift中有了可选类型的概念。(其实这一概念也是“借鉴”于其他编程语言,比如C#,只不过在C#中称之为可空类型).
大家在初看Optionals的感觉很陌生,在我第一眼看到它的时候,我就在想...这是什么鬼...但是仔细想想的话,可选值Optionals类型的引入,为我们也带了便利. 。
可选值(optionals)无可争议的是 swift 语言中最重要的特性之一,也是和其他语言,例如 Objective-C 的最大区别。通过强制处理那些有可能出现 nil 的地方,我们就能写出更有预测性的以及更健壮的代码.
然而,有些时候可选值可能会致你于尴尬的境地,尤其是你作为开发者了解(甚至是有些猜测的成分在),有的特定变量始终是非空(non-nil)的,即使它是一个可选类型。例如,我们在一个视图控制器中处理视图的时候:
1
2
3
4
5
6
7
8
9
10
11
|
class
TableViewController: UIViewController {
var tableView: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: view.bounds)
view.addSubview(tableView!)
}
func viewModelDidUpdate(_ viewModel: ViewModel) {
tableView?.reloadData()
}
}
|
这也是对于很多 Swift 程序员争论比较激烈的地方,程度不亚于讨论 tabs 和 spaces 的用法。有的人会说:
既然它是一个可选值,你就应该时刻使用 if let 或者 guard let 的方式进行解包.
然而另外一些人则采用完全相反,说:
既然你知道这个变量在使用的时候不会为 nil,使用 ! 强制解包多好。崩溃也要比让你的程序处于一个未知状态要好吧.
本质上来讲,我们这里讨论的是要不要采用防御性编程(defensive programming)的问题。我们是试图让程序从一个未知状态恢复还是简单的放弃,然后让它崩溃掉?
如果非得让我对这个问题给出一个答案的话,我更倾向于后者。未知状态真的很难追踪 bug,会导致执行很多不想执行的逻辑,采用防御性编程就会使得你的代码很难追踪,出现问题很难追踪.
但是,我不太喜欢给出一个二选一的答案。相反,我们可以寻找一些技术手法,用更精妙的方式的解决上面提到的问题.
它真的可选的吗?
那些可选类型的,但是被代码逻辑真实需要的变量和属性,实际上是架构瑕疵的一个体现。如果在某些地方确实需要它,但是它又不在,就会使得你的代码逻辑处于未知状态,那么它就不应该是可选类型的.
当然,在某些特定场景下,可选值确实很难避免(尤其是和特定的系统 API 交互的时候),那对于大部分这种情况,我们有一些技术来处理从而避免可选值.
lazy 要比非可选的可选值更好 。
某些属性的值需要在其父类创建之后再生成(比如视图控制器中的那些视图,应该在 loadView()或者 viewDidLoad()方法中被创建),对于这种属性要避免其可选类型的方法就是使用 lazy 属性。一个lazy属性是可以是非可选类型的,同时也不在其父类的初始化方法里被需要,它会在其第一次被获取的时候创建出来.
让我们改一下上面的代码,使用 lazy 来改造 tableView 属性:
1
2
3
4
5
6
7
8
9
10
11
|
class
TableViewController: UIViewController {
lazy var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.frame = view.bounds
view.addSubview(tableView)
}
func viewModelDidUpdate(_ viewModel: ViewModel) {
tableView.reloadData()
}
}
|
这样,没有可选值了,也不会有未知状态咯 。
最后此篇关于Swift中非可选的可选值类型处理方法详解的文章就讲到这里了,如果你想了解更多关于Swift中非可选的可选值类型处理方法详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我喜欢在 Lisp、Python 或 JavaScript 等(通常是动态的)语言中可以使用 boolean 运算符而不是条件来编写的简洁代码,如典型的: x = someString or "def
具体来说,我将 WPF 与 MVVM 一起使用。我有一个 MainWindow,它是一个 WPF 窗口,所有操作都在其中发生。它为其属性、命令等使用相应的 View 模型类。 我在 Applicati
对于我从 VB6 移植的应用程序,我有几个关于 CLS 合规性的烦人的编译器警告,包括: Name '_AnIdentifier' is not CLS-Compliant. Type of para
Module Unix 包含 time 函数来获取自 Epoch 以来的秒数,但是是否有一种独立于平台的方式来获取相同的值并确保代码在非-Unix 部署? 最佳答案 尽管有它的名字,Unix modu
我有一个 R 函数,它试图将每个“单词”的第一个字母大写 proper = function(x){ gsub("(? proper("Māori") [1] "MāOri" 显然,RE 引擎认为
我有一个包含两列的表格。一个是 auto_increment 说 columnA 而另一个是非 auto_increment 说 columnB。我想在 columnB 中执行两种类型的插入操作: 插
我遇到了这个错误,但无法调试它 helpers.c:136:1: error: control may reach end of non-void function IDE 在最后一行中说} 这是我的
我想检查一个数组在 C 中是否按 acs 或 desc 顺序排序。这是使用 mpicc -Wall -o file file.c 编译的结果,因为我稍后在代码中使用 MPI 库。 mypractice
我想了解编译器对 C 中的非 volatile 变量有哪些限制(如果有的话)。 我不确定这是否属实,但有人告诉我,如果您有以下代码: int x; ... void update_x() { lo
我的代码在 IE 中有效,但在 Firefox 中无效。我试图让 onmousedown 和 onmouseup 事件以及 swapFE、swapEF 和 setUpTranslation 函数在 I
我的问题是.. 是否可以在非 root 设备上静默自动更新应用程序?如果设备已 Root ,则它会使用 super 用户权限更新我的应用程序,否则不会。请回复谢谢! 最佳答案 无法在非 Root 设备
阅读了 PropertyAnimator 的文档后,似乎只要满足以下条件之一,我们就可以为每个对象设置动画, 如果您有权限,请将 setter 方法添加到类中。 使用您有权更改的包装器类,并让该包装器
所以我正在制作移动应用程序,并希望使用相同的 URL 创建链接以激活 iOS 和 Android 中的内容。我已经知道该怎么做了。我对 android 的 Intent 是这样的:
这个问题很接近我的问题,但又不完全是:List minimum in Python with None? .我需要考虑到列表中所有值都为 None 的可能性。 我有一种情况,我必须在数据库中查找一些数
如何从 Pandas 数据框中获取非“NaN”值的索引? 我的数据框是 A b c 0 1 q1 1 1 2 NaN 3 2 3 q2
对于数据框 df = pd.DataFrame([[np.nan, 3.0, 7.0], [0.0, 5.0, 8.0], [0.0, 0.0, 0.0], [1.0, 3.0, np.nan], [
我在 Android 中播放视频之前对其进行解密。当我解密它时,我想将它存储在 Android 私有(private)文件夹中,这样其他应用程序和用户就无法访问它 - 我已经查找了一些看起来像这样的代
我有一个非常大的 csv 文件,如下所示: 关键词,印象 下载 juegos gratis,951 パソコン kakaku com,451 公司 session ,155 租车,356
我有一个继承自 AbstractType 的表单生成器类,我需要解析如下路径: $uri = $router->generate('blog_show', array('slug' => 'my-bl
我想从 Android 应用程序中的一个原始文本文件中读取一些文本,并在应用程序中显示该文本文件中的一行。小部件。 对于 MainActivity,我编写了一个使用以下代码获取 InputStream
我是一名优秀的程序员,十分优秀!