swift编程开发

基础特性

可空类型的操作符

左边
右边
返回
使用示例及场景
可空实例绑定
if let va = vb, vc=va{
}
可空链式调用
va?.uppercased()
va?.append()—原地修改
隐式展开可空类型(是可空类型的一种)
??(nil合并运算符)
可空类型
对应的非可空类型
nil返回右边,否则左边的展开值

数组:

声明方式一:

var alist: Array<String>

声明方式二:

var alist: [String] = ["q","p","r"]

数据比较时,注意是有序的。

字典:

var dict1:Dictionary<String, Double> = [:]

var dict2 = Dictionary<String, Double>()

var dict3:[String:Double] = [:]

var dict4 = [String:Double]()

要点:

当用key去获取value时,如果没有值则返回的是value类型的可空类型。

技巧一:循环

for (key,value) in movieRatings{

}

技巧二:转换到数组

let va = Array(movieRatings.keys)

集合:

var groceryBag = Set<String>()

groceryBag.insert("qifwef")

for food in groceryBag{

print(food)

}

要点:不会重名,相当于distinct

有uion的方法针对两个set的取交集

有contain的方法针对set来判断元素存在

有intersection(_:)来找出两个set的都存在的元素set

有isDisjoint方法来判断两个set是否存在交集

函数:

func fname(外部参数名 内部参数名:[inout]类型)->(返回)类型{

return 返回值

}

注意:内部参数名就已经是显示参数名了,即在没有外部参数名时,使用函数时可以带着。而外部参数名更多是用于介词的辅助。当参数列表中有任一参数提升了层次,即用上了外部参数名,那么,有一个_符号是用来应付无关紧要的那个参数的外部参数名。如果要熟练玩味这两类参数名,一定是在使用中玩味出应用场景的概念。内部是函数微观算法层。外部是类型和指代层。

  • 变长参数

上面的变成<类型…>

  • 默认参数

直接用="defaultvalue"即可

  • in-out参数

调用时实参要加&修饰,以示要在函数内修改。

  • 多个返回值时

-> (returnvalue1: [Int], returnvalue2:[String])

  • guard语句

func …

{

guard let mv = name.middle else{

print("out func here.")

return

}

print(mv)

}

gurard守护的条件不足时提前返回。mv的可空类型没有值,或者为nil时,执行打印out func here.和返回。

如果守护的条件“不尴尬”时,就后面用其值了,print(mv)。

  • 闭包(高阶函数)

闭包通俗来说就是{},有时是嵌套在函数内的函数。但更多的指把函数为参数传值给函数和从函数内返回函数类型,注意返回是引用类型,传入可以匿名技巧。

高阶函数是至少要接受一个函数作为输入的。如:

数组的sorted(),map(),filter(),reduce()方法。在swift中sorted既可以用传入参数的语法:

vv.sorted(by: sortAscending)

也可以使用匿名函数法。即闭包表达式的应用:

vv.sorted(by:{(i:Int,j:Int)->Bool in

return i<j

})

利用类型推断,再进化一下:

vv.sorted(by:{(i,j in i<j})

最终版本:

vv.sorted(by:{$0 < $1})

因为数组的元素类型是默认的了。

对象特性/技术

枚举:

要点:第一次创建枚举的变量就必须要初始化。

枚举类型可以没有原始值,即一定要归成Int类型。当然也可以用原始值,并指定初始值。不局限成Int类型的。

细分应用场景:

有限的

计算的,可修改

技巧:

mutation func XXX…

说明这个函数会修改对象中的值。

结构:

细分应用场景

无限的

计算的,要修改,简单继承扩展

无复杂关联操作的

技巧:

mutation func XXX…

说明这个函数会修改对象中的值。

static func XXX…

说明这个函数是类型方法

类:

细分应用场景

无限的

计算的,要修改,要控制继承及可见性

复杂关联,可见性的

总之,继承,封闭,多态。

技巧:

[final] [override/static] [class] func XXX…

说明final class == static符号,关闭子类重写本方法的意思。所以class和static两个符号在结构和类中是不同涵义的。(结构中没有class关键字)

属性:

  • 嵌套属性

类作用域中的枚举或结构,比如某一个枚举Size(类的接下来的属性会用到。)

  • 存储属性

此类型属性必须有值,默认也可,后初始也可,这主要和下面的类型区别。只读的存储类型==常量

  • 惰性存储属性

lazy var townSize:Size = {

switch selft.population{

case 0…10_000:

return Size.small

….

}

}()

注意:后面还有一对小括号,就说明这是一个运行得出的属性。但依赖的population是一个存储属性。类一初始化就已经给定,所以,算法也是一并初始就定了。而且,后面不会重新计算了。这块取义依赖的成分大于惰性。

  • 计算属性

var townSize:Size {

get{

switch selft.population{

case 0…10_000:

return Size.small

….

}

}

set(){

}

}

  • 属性观察者

var population = 5_422 {

didSet(oldpopulation){

}

}

  • 类型属性

此类属性的值在同类型实例间共享。但必须有默认值(原因是没有初始化方法的)。

在类中的可以用class修饰来让子类继承覆盖,也可以用static来禁止覆盖。

适合将没有入参的行为改写成类型属性。

  • 访问控制

描述
对who可见
能继承使用
open
Public
internal(默认)
fileprivate
private

初始化方法

  • 结构体的默认初始化

var myTown = Town()

结构体的成员初始化

var myTown = Town(population:10_000, numberOfStoplights:6)

  • 结构体自定义初始化

委托初始化(在结构体中称为这个,在类中同义但是称为便捷初始化)

init(){

self.init()

}

  • 类的初始化(在类的继承场景中)

指定初始化

init(){

//初始化本类引入的属性

super.init()//调用父类中的初始化方法

}

便捷初始化

convenience init(){

selft.init()//本地的初始化,其中也可能调用指定的初始化,层层初始。

}

必需初始化

父类中要求

required init

子类中实现,关键字包括了Overrider的意思。

required init

反初始化方法

deinit{

}

高级特性

协议

枚举,结构体,类都可遵守协议,同时协议也可以继承,也可使用&来组合(用于传递参数)。可以理解它为是样貌。

protocol Velocity{

}

异常

func getNumber() throws -> Int{

throw 类中枚举的异常值

}

使用上面的函数时便可try getNumber()

或者在外层包裹:

do{

try get…

anotherfunc()

}catch Parse.Error.unexceptedEndOfInput{

}catch{

}

扩展

注意针对是类型,且是可以针对协议的。强大的冒汗了。可以理解成它是样式

typealias Velocity = Double

extension Velocity {

}

泛型和协议扩展的争论

泛型是固化一种模式算法,而扩展是让对象本身增量元素或行为,即样式或样貌。

所以,会用泛型,你要先具备知识,知晓有了某种前人栽的树,即知道已经有满足的可用的公共泛型函数了。

而用协议扩展,你就要自己栽树,但只给自己用在自己的地里。