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. [HttpClient]传递参数

    package com.jerry.httpclient; import java.io.UnsupportedEncodingException; import java.util.ArrayLis ...

  2. dedecms 文章内容文章名字和文章网址的调用

    文章标题: <a href="{dede:field name='arcurl'/}">{dede:field.title/}</a> 本文章网址: < ...

  3. 支付宝支付错误 系统忙:错误代码AE150002999

    今天出现支付宝支付错误,支付系统繁忙请稍等,错误码AE150002999.测试了其他连个收款方,可跳转到正常扫码支付页面,排除了代码错误. 在登录支付宝商家中,也签约了“即时到帐”功能.度娘和查看都找 ...

  4. ubuntu更新源

    源一定要找对应的版本 14.04对应 trusty deb http://mirrors.163.com/ubuntu/ trusty main restricted universe multive ...

  5. C语言结构体(struct)使用方法

    基本定义:结构体,通俗讲就像是打包封装,把一些变量有共同特征(比如同属于某一类事物的属性)的变量封装在内部,通过一定方法访问修改内部变量. 结构体定义: 第一种:只有结构体定义 struct stuf ...

  6. 《C和指针》章节后编程练习解答参考——6.1

    <C和指针>——6.1 6.1 题目: 编写一个函数,在一个字符串中进行搜索,查找另一子字符串中出现的字符. 函数原型如下: char *find_char(char const *sou ...

  7. 未能加载文件或程序集XXX或它的某一个依赖项。试图加载格式不正确的程序。

    今天发布网站时,老是弹出下面这样一个错误. 经过一番折腾终于找到答案: 方法一: 在IIS中设置, 属性 ——常规—— 启用32位应用程序 修改为True. 方法二: 修改项目属性——生成——目标平台 ...

  8. [BZOJ 3236] [Ahoi2013] 作业 && [BZOJ 3809] 【莫队(+分块)】

    题目链接: BZOJ - 3236   BZOJ - 3809 算法一:莫队 首先,单纯的莫队算法是很好想的,就是用普通的第一关键字为 l 所在块,第二关键字为 r 的莫队. 这样每次端点移动添加或删 ...

  9. 23个经典JDK设计模式(转)

    下面是JDK中有关23个经典设计模式的示例: Structural(结构模式) Adapter: 把一个接口或是类变成另外一种. o    ● java.util.Arrays#asList() o  ...

  10. java学习面向对象之设计模式之单例模式

    就像上一节当中我们讲到的数组工具集一样,如果我们把他看作一个类,来应用,不阻止他new函数的话,这个类我们在整个过程当中我们只是用他来当一个工具.假如每次用都要new一下产生一个新对象的话,就会显得整 ...