原文ghui.me欢迎指教
Swift的构造器的编写规则要比其它语言麻烦很多, 有很多限制, 有些限制也不是那么容易想明白的, 但我想Swift的设计者肯定是有自己的考虑,不会平白无故的去设置这些限制,在这篇文章中我将试着总结一下Swift语言在构造过程中的种种限制以及为什么会需要这些限制.
1: Swift会为构造器的每个参数自动生成一个跟内部名字相同的外部名
构造器并不像函数和方法那样在括号前有一个可辨别的名字(构造器统一叫init
), 为了提高构造器的可读性就有了这条限制, 当然如果你实在是不想为构造器提供外部名,可以使用下划线_
来显式描述它的外部名, 这样就不会有上述默认行为了.
2: 任何一个构造器都必须使当前对象内的非lazy
非Optional
类型的存储属性获得确定值
如果你之前做过Java开发, 你可能会对这一点产生疑惑, 在Java的构造器里我们是不需要对所有的字段显示进行赋值的.
其实这个和Swift引入的Optional
有关,在Swift中非Optional
的变量默认是不会有值的, 除非你将它显示的定义为Optional
的, 换句话说Swift中Optional
类型的变量才相当于Java中的变量(java中的全局变量会自动被赋予默认值).而Swift中Optional类型的变量才会有默认值nil, 而且构造器的目的就是分配内存以及使当前对象处于一个确定的状态(属性都有值包括nil)
3: 如果结构体或类的所有的属性都有默认值, Swift才会为它们提供默认构造器
在java中如果你没有定义构造器, Java就会自动为你提供一个默认构造器, Swift为什么不?
基实这个和限制2的原因是一样的, 首先构造器要保证当前对象所有的属性都有值, 而Swift中的非Optionl类型的变量没有默认值, 所以只有当所有属性都有默认值的情况下Swift才能提供默认构造器.
4: 如果你自定义了构造器, 那么默认构造器会丢失(如果是结构体,还将丢失逐一成员构造器)
这种限制可以防止你为值类型增加了一个额外的且十分复杂的构造器之后,仍然有人错误的使用自动生成的构造器. 如果你想保留默认构造器逐一成员构造器以及你自己定义的构造器,你可以将自定义构造器定义到extension中
5. 指定构造器与便利构造器是针对类而言的, 值类型的构造器没有这一说
6. 指定构造器必须总是向上代理, 便利构造器必须总是横向代理
之所以要这样规定, 官方的说法是为了简化指定构造器与便利构造器之间的调用关系:
1: 指定构造器必须调用其直接父类的的指定构造器
2: 便利构造器必须调用同一类中定义的其它构造器
3: 便利构造器必须最终导致一个指定构造器被调用

网友评论