Failable Initializers

有的时候,可能是参数问题、需要的外部资源没有到位等原因,初始化可能失败。为了应对这种情况,我们可以定义一个或多个可失败的构造方法。 init?

A failable initiazlier creates an optional value of the type it initializes.

通过返回nil来表示初始化失败,看个例子:

struct Animal {
let species: String
init?(species: String) {
if species.isEmpty {
return nil
}
self.species = species
}
} let someCreature = Animal(species: "Giraffe")
//someCreature的类型是Animal?
if let giraffe = someCreature {
//
}

Failable Initializers for Enumerations

enum TemperatureUnit {
case kelvin, celsius, fahrenheit
init?(symbol: Character) {
switch symbol {
case "K":
self = .kelvin
case "C":
self = .celsius
case "F":
self = .fahrenheit
default:
return nil
}
}
} let fahrenheitUnit = TemperatureUnit(symbol: "F")
if fahrenheitUnit != nil {
print("This is a defined temperature unit, so initialization succeeded.")
}
// Prints "This is a defined temperature unit, so initialization succeeded." let unknownUnit = TemperatureUnit(symbol: "X")
if unknownUnit == nil {
print("This is not a defined temperature unit, so initialization failed.")
}

Failable Initializers for Enumerations with Raw Values

Enumerations with raw values automatically receive a failable initializer, init?(rawValue):), that takes a parameter called rawValue of the appropriate raw-value type and selects a matching enumeration case if one if found, ro triggers an initialization failure if no matching value exists.

把上面的例子改写一下:

enum TemperatureUnit: Character {
case kelvin = "K", celsius = "C", fahrenheit = "F"
} let fahrenheitUnit = TemperatureUnit(rawValue: "F")
if fahrenheitUnit != nil {
print("This is a defined temperature unit, so initialization succeeded.")
}
// Prints "This is a defined temperature unit, so initialization succeeded." let unknownUnit = TemperatureUnit(rawValue: "X")
if unknownUnit == nil {
print("This is not a defined temperature unit, so initialization failed.")
}

Propagation of Initialization Failure

一个类、结构体、枚举的可失败的构造方法可以delegate across同一个类型中另一个可失败的构造方法。子类的一个可失败的构造方法可以delegate up父类的可失败的构造方法。

一个可失败的构造方法也可以delegate to不可失败的构造方法。

看个例子:

class Product {
let name: String
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
} class CartItem: Product {
let quantity: Int
init?(name: String, quantity: Int) {
if quantity < 1 { return nil }
self.quantity = quantity
super.init(name: name)
}
}

Overriding a Failable Initializer

父类的可失败的构造函数可以被重写为可失败的或者不可失败的。看个例子:

class Document {
var name: String?
// this initializer creates a document with a nil name value
init() {}
// this initializer creates a document with a nonempty name value
init?(name: String) {
if name.isEmpty { return nil }
self.name = name
}
} class AutomaticallyNamedDocument: Document {
override init() {
super.init()
self.name = "[Untitled]"
}
override init(name: String) {
super.init()
if name.isEmpty {
self.name = "[Untitled]"
} else {
self.name = name
}
}
}

The init! Failable Initializer

init! implicitly unwrapped optional instance

Required Initiazliers

在构造方法的定义前边加上required修饰符来表示这个类的每一个子类都必须实现这个构造方法:

class SomeClass {
required init() { }
}

当重写一个required指定构造器时,不用在前边加override修饰。

注意:如果你可以使用一个继承的构造方法来满足的话,那么你可以不提供一个显式的required构造方法。

比如说我们定义一个子类:

class SomeSubClass: SomeClass {
required init() {
//
}
}

这样写,没有问题。我们也可以这样写:

class SomeSubClass: SomeClass {

}

这样写也没有问题,因为init()方法被自动继承了。我们接着看:

class SomeSubClass: SomeClass {
init(name: String) {
//
}
}

这样因为我们自定义了一个指定构造方法,SomeSubClass不会自动继承父类的指定构造方法(init()),所以编译器会提示我们一个错误。

Setting a Default Property

主要用途是为存储属性进行一些处理,可以使用全局函数或者闭包。看起来大概是这个样子:

class SomeClass {
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
}

Swift: Initialization-2的更多相关文章

  1. iOS: 聊聊 Designated Initializer(指定初始化函数)

    iOS: 聊聊 Designated Initializer(指定初始化函数) 一.iOS的对象创建和初始化 iOS 中对象创建是分两步完成: 分配内存 初始化对象的成员变量 我们最熟悉的创建NSOb ...

  2. Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removing it

    Swift 提示:Initialization of variable was never used consider replacing with assignment to _ or removi ...

  3. Swift - 初始化Initialization

    Ps:苹果官方文档-Initialization 自定义控件初始化中常见的几种错误(指定构造器和便利构造器)截图:   意思是:1.没有添加重写符override(重写父类方法)2.没有重写initW ...

  4. Swift中懒加载(lazy initialization)的实现

    Swift中是存在和OC一样的懒加载机制的,但是这方面国内的资料比较少,今天把搜索引擎换成了Bing后发现用Bing查英文\最新资料要比百度强上不少. 我们在OC中一般是这样实现懒加载初始化的: 1: ...

  5. Lazy Initialization with Swift

    Lazy initialization (also sometimes called lazy instantiation, or lazy loading) is a technique for d ...

  6. Swift - 懒加载(lazy initialization)

    Swift中是存在和OC一样的懒加载机制的,在程序设计中,我们经常会使用 懒加载 ,顾名思义,就是用到的时候再开辟空间 懒加载 格式: lazy var 变量: 类型 = { 创建变量代码 }() 懒 ...

  7. Swift 的类、结构体、枚举等的构造过程Initialization(下)

    类的继承和构造过程 类里面的全部存储型属性--包含全部继承自父类的属性--都必须在构造过程中设置初始值. Swift 提供了两种类型的类构造器来确保全部类实例中存储型属性都能获得初始值,它们各自是指定 ...

  8. Swift学习笔记十四:构造(Initialization)

         类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态.     你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...

  9. swift语言点评十六-Initialization && Deinitialization

    initial value:必须初始化.不影响观察者 Classes and structures must set all of their stored properties to an appr ...

  10. Swift 2 语言精要 - Initialization and Deinitialization

    init相当于构造函数 deinit相当于析构函数 class InitAndDeinitExample { // Designated (i.e., main) initializer init ( ...

随机推荐

  1. js中的潜伏者之Arguments对象

    argument 说明: 在JavaScript中,arguments是对象的一个特殊属性.arguments对象就像数组,但是它却不是数组.可以理解为他是潜伏者,通俗的说,就是你传的参数不一定按照参 ...

  2. HTML 动态显示系统当前时间

    HTML 动态显示系统当前时间: <div id="time"> <script> document.getElementById('time').inne ...

  3. apache 设置404页面

    这几天用xampp搭建了一套环境,后来发现在网页访问出现404的时候xampp显示的内容不安全,把apache.php还有一些其它的版本都会显示 出来,所以想自己设置一个404的页面,在网上找了一些资 ...

  4. Python 环境

    文章出处:http://www.cnblogs.com/winstic/,请保留此连接 总结一下自己使用python过程中安装三方包的方法 Python 安装 Python的安装非常简单,本人使用的w ...

  5. javascript定义类的方法总结

    1.构造函数法 类是对象的模板,定义了对象共有的方法属性数据 等,在javascript中一个函数就是一个对象,也可以看做一个类的构造方法. 所以我们可以像以下方式定义类: //1.经典的构造方法 Q ...

  6. CentOS 6.3 配置FTP

    一.FTP的安装 .检测是否安装了FTP:[root@localhost ~]# rpm -q vsftpd 如果安装了会显示版本信息: [root@localhost ~]# vsftpd-2.0. ...

  7. hadoop输出统计

  8. BZOJ 3243 向量内积

    Description 两个\(d\)维向量\(A=[a_{1},a_{2},...,a_{d}]\)与\(B=[b_{1},b_{2},...,b_{d}]\)的内积为其相对应维度的权值的乘积和,即 ...

  9. zip file 压缩文件

    有时候我们希望 upload 文件后自动压缩, 可以节省空间. 可以使用微软提供的压缩代码 Install-Package System.IO.Compression.ZipFile -Version ...

  10. ArrayList LinkedList Vector

    ArrayList是基于数组实现的,没有容量的限制. 在删除元素的时候,并不会减少数组的容量大小,可以调用ArrayList的trimeToSize()来缩小数组的容量. ArrayList, Lin ...