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 call和apply用法(转)

    每个JavaScript函数都会有很多附属的(attached)方法,包括toString().call()以及apply().听起来,你是否会 感到奇怪,一个函数可能会有属于它自己的方法,但是记住, ...

  2. Centos6.2_(64位)服务器环境配置:源码编译Nginx

    目标软件都指定安装目录:/apps.由于Nginx可以使用正则表达式来匹配访问路径, 要正常使用此功能就保证安装有Pcre库,如果你已经接着上一篇操作过来,就可以不用考虑这一点,因为此库已经在安装列表 ...

  3. POJ1611-The Suspects-ACM

    The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 23002   Accepted: 11171 De ...

  4. POJ3274-牛的属性-HASH-ACM

    原题:POJ3274 参考:进击的阿俊 已知有n头牛,用一个K位二进制数Ak,Ak-1,...,A1表示一头牛具有的特征,Ai=1表示具有特征i.现给定按顺序排列的N头牛的k位特征值,称某个连续范围内 ...

  5. sphinx(coreseek)——1、增量索引

    首先介绍一下     CoreSeek/Sphinx的发布包 indexer: 用于创建全文索引;    search: 一个简单的命令行(CLI) 的测试程序,用于测试全文索引;    search ...

  6. 使用C语言获取当前系统的时间

    要想使用C语言来获取当前系统的时间,办法如下: 需要提前准备的工作: #include <stdio.h> #include <time.h> #include <std ...

  7. Java高精度学习第三弹——ACM中使用JAVA的详细介绍

    Chapter I. Java的优缺点各种书上都有,这里只说说用Java做ACM-ICPC的特点: (1) 最明显的好处是,学会Java,可以参加Java Challenge . (2) 对于熟悉C/ ...

  8. .net序列化和反系列化json与类型对象转换

    先添加程序集:  System.Web.Extensions(在 System.Web.Extensions.dll 中) 引用:using System.Web.Script.Serializati ...

  9. Cylinder

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2374 思路:三分枚举. #include &l ...

  10. JavaScript encodeURI() 函数

    encodeURI() 函数可把字符串作为 URI 进行编码. -------------------------------------------------------------------- ...