注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风的驿站

一徐清风,半指烛光,觥筹已净,只余茶香。残卷一章,妙趣非常,忽闻帘响,愿闻其详?

 
 
 

日志

 
 
关于我

喜欢写生 编程 音乐 设计 喜欢把自己的想法变成实实在在的东西 喜欢安静的做一些事情 CSDN博客:http://blog.csdn.net/qwertyupoiuytr

网易考拉推荐

【原创】Swift语言学习笔记(六)  

2014-07-17 22:42:18|  分类: Swift |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

97.  可选链(optional chaining)的例子:

class A {

    var m : Int = 10

}

class B {

    var a : A?

}

class C {

    var b : B?

}

var c = C()

var k = c.b?.a?.m

println(k)

上面的例子中,我们在为变量k赋值的时候,使用的是c.b?.a?.m,这里并没有使用c.b!.a!.m,否则由于b或者a是空,会抛出运行时的异常。而使用“?”,会导致返回一个Int?k,尽管属性“m”的类型是Int,并不是Int?,可选链避免由于元素为nil导致异常的发生。

甚至还可以使用可选链来检测方法是否执行成功,甚至是无返回值的方法(无返回值的方法实际返回的是Void?),如果函数的返回值是nil,则表明函数执行失败,否则表示函数成功执行。

对于下标(subscript)使用可选链,问号要位于下标的中括号前面,例如:

var v = someClassInstance1.subClassInstance1?[0].prop

对于函数使用可选链,问号位于函数圆括号的后面:

var v = someClassInstance1.fun1()?.prop

98.  Swift中使用isas来进行类型转换的判断以及转换。其中as运算符会强制转换为目标类型,如果转换失败会抛异常,所以,如果在不确定转换是否成功的情况下,使用as?运算符,转换失败会返回nil

99.  Swift中的变量绑定会自动将可选类型变量的值解出来,例如:

var i : Int? = 10

var t = (i, 0)

switch t {

case (let m, 0):

    println(m)

default:

    break

}

例子中常量m直接得到的就是可选类型变量i存储的Int值。

100.           Swift中提供AnyObjectAny两种特殊类型,AnyObject可以用来指向任何类的实例,Any可以指向任何类型的实例,除了函数类型。例如:

var a : AnyObject = SomeClass()

var a : Any = 10

101.           Swift中可以使用as将数组类型批量做类型转换,例如:

class A {

}

var someObjects : AnyObject[] = [A(), A(), A()]

var arr = someObjects as A[]

102.           Swift中允许使用类型嵌套,类型嵌套直接在一个类型定义中嵌套另一个即可:

class A{

    class B {

        enum C {

            case C1, C2, C3

        }

    }

}

要使用嵌套类型,用类名引用:

var c = A.B.C.C1

103.           Swift中通过扩展(extension)来为已知类、结构体或者枚举类型添加功能,类似于Object-C中的categorySwift中的扩展可以添加的内容:

计算属性(getset方法)和静态计算属性

类方法和实例方法

初始化方法

下标(subscript

嵌套类型

协议继承关系

104.           Swift中扩展使用extension关键字来定义:

extension SomeType {

}

extension SomeType : SomeProtocol {

}

105.           Swift中扩展可以添加初始化方法,但是不能添加指派初始化方法,也不能添加析构方法。

106.           在定义类的时候,如果类既有基类,又实现了某些协议(protocol),那么在声明的时候,一定要把基类写在最前面:

class ClassName : BaseClassName, ProtocolName1, Protocol2… {

}

107.           Swift中的协议(protocol)可以定义继承类必须实现的属性,属性可以使只读的,也可以是读写的(注意,协议中定义的属性都是用var关键字,静态属性和方法都使用关键字class):

protocol DemoProtocol {

var prop1 : Int { get set }

var prop2 : String { get }

}

虽然在定义的时候使用get/set来指明属性的读写性质,但是实现类中并没有要求一定要定义属性的getset方法,只要实现类中存在名称相同类型一致的属性即可。要注意的一点限制是:如果协议中定义的属性为读写属性,则实现类中对应属性不能为常量或者只读属性。

108.           Swift协议中定义的方法不能指定参数默认值。

109.           Swift中协议可以继承其他协议(C#中也可以),语法和类定义类似。

110.           如果需要“一个”类型同时继承多个协议时,可以使用protocol<Protocol1, Protocol2, …>来将多个协议组装成一个整体,例如:

protocol P1 {

}

protocol P2 {

}

protocol P3 {

}

class C1 : P1, P2, P3 {

}

func demoFunc(demoClass : protocol<P1, P2, P3>) {

}

var c = C1()

demoFunc(c)

这种组装只能是临时的一个类型,不能作为一种新的协议类型来定义变量等。

111.           对于协议类型,也可以使用isasas?来进行类型判断和类型转换,但是如果想要使用is关键字来判断类型,必须要在protocol关键字前面添加@objc关键字来进行修饰,且使用@objc来修饰的协议不能被结构体和枚举类型继承,asas?关键字不需要这个要求。例如:

@objc protocol DemoProtocol { }

class A : DemoProtocol { }

class B { }

struct B : DemoProtocol { }             //这行编译不过去

var a : AnyObject = A()

var b : AnyObject = B()

var c : Bool = a is DemoProtocol

var d = b as? DemoProtocol           //d = nil

注意我们定义变量a的时候特意定义a的类型为AnyObject,如果不这样做,会提示我们“a is DemoProtocol”这句有错误,因为如果a不定义成AnyObject,编译器会推测出a的类型为A,继承DemoProtocol协议,因此a is DemoProtocol这句永远为真,所以会报错来提示我们去掉不必要的语法。

112.           使用@objc关键字定义的协议中可以定义可选(optional)的方法和属性,通过在方法和属性的声明最前面添@optional关键字来实现。例如:

@objc protocol DemoProtocol {

@optional func demoFunc()

@optional var demoProp

}

对于可选的方法和属性,继承类可以选择实现或者不实现。因此,在调用时为了保证程序能正常运行,不会因为方法或者属性没有实现而抛异常,在调用的时候在方法名或者属性后面添加?(和可选链的用法相同)来保证返回可选类型。

113.           Swift中的泛型方法定义:

func genericFuncDemo<T>(para1 : T, para2 : T …) {

}

调用的时候很简单,不需要显式地指明T的类型:

var p1 = “abc”

var p2 = “def”

genericFuncDemo(para1 : p1, para2 : p2 …)

可以定义多个占位类型:

func demoFunc<T, U, P>(para1 : T, para2 : U, para3 : P …) {

}

114.           Swift中的泛型类、泛型结构体和泛型枚举类型的定义都是在类名和结构体名后面加上<>,里面填写泛型的占位类型,例如上面的TUP这些。占位类型的命名最好用大写开头,以表明它是一个类型而非一个值。

115.           可以在定义泛型的时候使用类型约束,例如:

func someFunc<T : SomeClass, U : SomeProtocol>(a : T, b : U) {

}

例如可以定义T继承EquatableU继承Comparable

116.           Swift中可以为协议定义关联类型,使用typealias关键字来定义关联类型,一个协议中可以定义多个关联类型,例如:

protocol Container {

typealias ItemType

mutating func append(item : ItemType)

var count : Int { get }

subscript(i : Int) -> ItemType { get }

}

上面的关联类型保证了Container中的append方法添加的元素和下标取出的元素类型一致。

下面的结构体实现Container协议中定义的方法,通过typealias ItemType = Int来指定具体的关联类型是Int型:

struct IntStack : Container {

var items = Int[]()

typealias ItemType = Int

mutating func append(item : Int) {

    items.append(item)

}

var count : Int {

    return items.count

}

subscript(i : Int) -> Int {

    return items[i]

}

}

实际上,即使不写typealias ItemType = Int这条语句,Swift也能够推测出ItemTypeInt型,编译也能够正常通过,这是因为IntStack中实现了所有Container中定义的方法。

也可以结合泛型和关联类型,例如将上面的IntStack改成泛型结构体。

117.           除了泛型约束之外,还可以使用where子句来对泛型加以约束,例如:

func isAllItemsMatch<C1 : Container, C2 : Container where C1.ItemType = C2.ItemType, C1.ItemType : Equatable>(someContainer : C1, anotherContainer : C2) -> Bool {

    //compare every element in the two containers

}

where子句中可以使用andor来进行逻辑连接。


  评论这张
 
阅读(93)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017