味道

想念你的笑
想念你的外套
想念你白色袜子
和身上的味道
我想念你的吻
和手指淡淡烟草味道
记忆中曾被爱的味道
----For Swift

2ca603ec-0911-43b3-837f-becd2671a58e.png

咳咳```一不小心唱起来了,味道。
说点实在的,Swift的味道还真是不得不让人迷醉。
三周之前,我不认识你,你不属于我;三周之后,我依然不认识你,你也不属于我。唯有的,只有我记住了你的一些味道:袜子味儿、辣椒味儿、火药味儿、无重复的味儿……当然,更多的,是清香味儿,来的轻盈,散的清凉。


容器

“Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values”

Swift 用来存储数据的三种类型:数组、集合、容器

- 数组

数组有三种最重要的运算:过滤、映射、缩减

let array = [2,24,56,96,68,88,44,37,1]
//1.过滤
let newarray = array.filter { $0 % 2 == 0}
print(newarray)//过滤奇数  [2, 24, 56, 96, 68, 88, 44]

//2.映射
let newArray2 = array.map { $0*$0}//每个对应平方
print(newArray2)//[4, 576, 3136, 9216, 4624, 7744, 1936, 1369, 1]

//3.缩减
let reduce1=array.reduce(0, combine: +)
print(reduce1)//416


- 集合

以hash code/哈希码/散列码 来存储数据,使用时很快就能找到其中某个数据的位置和值,型如:var a:Set<Int> = [1,1,5,4,2]
对集合的操作:
1.增删

a.insert(100)     //添加元素
a.remove(1)     //   删除元素
print(a)          //  [5, 100, 2, 4]

2.交并差子

var b:Set<Int> = [1,2,33,7]
print(a.intersect(b))//交集    [2]
print(a.union(b))    //并集    [2, 4, 5, 100, 7, 1, 33]
print(a.subtract(b))  //差集  [5, 100, 4]
var c:Set<Int>  =  [5,100]
print(c.isSubsetOf(a))//判断子集(Bool)  true

- 字典

字典的每个元素都是由两个方面组成,冒号前是键,冒号后是值
通过键获取对应的值(可空类型,因为给的键有可能没有对应的值)
如:

var dict :[String:String] = ["abacus":"算盘","abnomal":"异常","hello":"你好","good":"好"]
print(dict["hello"]!)  //你好
print(dict["sss"])   //nil

遍历字典

for value in dict.values{
    print(value)
}

for key in dict.keys{
    print(key)
}
for (key,value) in dict{
    
    print("\(key)-->\(value)")
}
/*结果:
abnomal
shit
hello
good
abnomal-->异常
shit-->🐶💩
hello-->你好
good-->好
*/

枚举

两种相反的事物,我们义无反顾的选择Bool类型,那么超过两种但却又相互对立的事物,怎么描述呢?那么枚举就是必不可少的了。利用自定义的枚举类型,可以在项目中任意调用其中一种事件,比如,扑克有四种花色,利用枚举,就可以便捷的定义区分花色了

花色枚举
- Spade: ♠️
- Heart: ♥️
- Club: ♣️
- Diamond: ♦️

enum Suite:String{
    case Spade = "♠️",Heart = "♥️",Club = "♣️",Diamond = "♦️"
}

……
……

let suites = [Suite.Spade, .Heart,.Club,.Diamond]

函数

swift中,函数也是一种类型,这也意味着函数可以作为常量或者变量的类型。
同理,函数可以作为另一个函数的参数或者返回值.

- 尾随闭包

闭包:就是Java和C#中的 lambda函数(lambda表达式)、JS中的匿名函数,C中的B look起相同作用的,他存在的意义是,实现代码的解耦合
毕竟,写代码的终极目的,高类聚,低耦合
闭包的形式为:

  { (parameters) -> return type in
    statements
  } 

这里的return可以省略。如果函数的最后一个参数是闭包,可以写成尾随闭包的形式,也就是将闭包放到函数参数的圆括号外面写一对花括号中;如果函数后面有尾随闭包且函数的圆括号里没有参数,那么圆括号可以省。

尾随闭包
如果函数的最后一个参数是闭包。可以将该参数放到函数的花括号内,省略圆括号()

reversed = names.sort { $0 > $1 }

数组names降序排列。
$0表示第一个参数
$1表示第二个参数

- 递归调用

递归,指的就是一个函数直接或间接调用自身的方法,其条件为:
1.递归公式
2.收敛条件
简单举个例子,用递归方法可以算1-100的求和:

func sss(n:Int)->Int{
    if n==1{
        return 1
    }
    return n + sss(n-1)
}

这里的sss函数,两个分支,一个是当n!=1的时候,再次调用自身,就是计算100的函数要调用99的函数,99的函数需要调用98的函数……直到调用到1,直接返回1,即可求出结果。这里,递归公式就是函数的return n + sss(n-1),递归条件是,当n==1的时候,停止递归,返回 给上一次的递归结果1.
经典应用:汉诺伊塔

func hanluoita(n:Int,_ a:String,_ b:String,_ c:String)
{
    if n>0{
        hanluoita(n-1, a, c, b)
        print("\(a)--->\(b)")
        hanluoita(n-1, c, b, a) 
    } 
}
hanluoita(5, "A", "B", "C")

物以类聚,人以群分。故名思义,类,就是具有相同的属性的一个概括。
定义一个类主要有四个步骤:
发现类

  • 在对问题的描述中找名词和动词
  • 名词会成为类或者类中的属性 动词会成为类中的方法

定义类

  • 定义类可以创建新的类型,类名每个首字母大写;
  • 数据抽象--找到和学生相关的属性(找名词)
  • 初始化方法\构造方法--创建对象要使用的方法--constructor
  • 行为抽象--找到和学生相关的方法(找动词)
    变量定义在类里,叫属性;函数写在类里面,叫方法

创建对象

  • 调用初始化方法

给对象发消息

  • 通过给对象发消息来解决问题

面向对象

面向对象七原则:(为了实现高类聚、低耦合)
  • 单一职责原则(SRP)
    每个类应该专注于做一件事情哦

  • **开闭原则(OCP) **
    面向扩展开放,面向修改关闭

  • 依赖倒转原则(面向抽象编程, DIP)
    实现尽量依赖抽象,不依赖具体实现

    爱人, 待周爱人而后为爱人
    《墨子·取周》

  • **里氏替换原则(LSP) **
    能用父类型的地方就一定可以使用子类型.超类存在的地方,子类是可以替换的

    白马, 马也, 乘白马, 乘马也
    黑马, 马也, 乘黑马, 乘马也
    娣, 美人也, 爱娣非爱美人也
    盗, 人也, 恶盗非恶人也
    《墨子·小取》

  • ** 接口隔离原则(ISP)**
    应当为客户端提供尽可能小的单独接口,而不是提供大的总的接口

  • 合成聚合复用原则(CARP)
    尽可能使用合成/聚合达到复用,尽量少用继承。原则:一个类中有另一个类的对象

  • 迪米特法则(LoD)
    一个软件实体应当尽可能少的与其他实体发生相互作用

继承

继承: 从已有的类创建新类的过程
提供继承信息的称为父类(超类/基类);得到继承信息的称为子类(派生类/衍生类)
通常子类除了得到父类的继承信息还会增加一些自己特有的东西
所以子类的能力一定比父类更强大.
继承的意义在于子类可以复用父类的代码并且增强系统现有的功能.

继承特点:
  • 可以将子类型的对象赋值给父类型的变量(因为子类跟父类之间是IS-A关系)
  • 如果要将父类型的变量转换成子类型需要用as运算符进行类型转换
  • 如果能够确认父类型的变量中就是某种子类型的对象可以用as!进行转换
  • 如果不确定父类型的变量中是哪种子类型可以用as?尝试转换
  • 定义方法参数类型的时候尽可能使用父类型(抽象类型).因为如果用父类型的参数调用方法时可以传入任意子类型对象

多态

同样的对象类型接收相同的消息(调用相同的方法),但是做了不同的事情 这就是多态(polymorphism)
实现多态的关键步骤:

  1. 方法重写 override (子类在继承父类的过程中对父类已有的方法进行重写, 而且不同的子类给出各自不同的实现版本)
    父类有的方法子类可以重新实现 这个过程叫方法重写,需要在方法前添加override关键字.重写有时也被称为置换/覆盖/覆写
  2. 对象造型(将子类对象当成父类型来使用)

可以通过if+as?将父类型安全的转换成子类型然后再调用子类特有方法

一些技能GET ✔️

  • 便利构造器
    我们可以在一个类中定义多个初始化方法
    便利初始化方法 / 便利构造器:
    调用了其他的初始化方法的初始化方法
 convenience init() {
        self.init(x: 0, y: 0)
    }
    convenience init(point: (Double, Double)) {
        self.init(x: point.0, y: point.1)
    }
    ```
  **指派初始化方法 / 指派构造器**:
    被其他初始化方法调用的初始化方法

init(x: Double, y: Double) {
self.x = x
self.y = y
}


   -  **计算属性**
在定义类的属性的时候,有两种方式:
存储属性:负责存储变量的值
计算属性:负责将存储数据进行计算返回新的值,有get和set方法
如果不允许修改的变量,就没有set方法,通过私有的方法保护原来的值。

//存储属性
private var _name: String
private var _hp: Int
private var _mp: Int

//计算属性
var isAlive: Bool {
get { return _hp > 0 }
}
var name: String {
get { return _name }
}
var hp: Int {
get { return _hp }
set { _hp = newValue > 0 ? newValue : 0 }
}
var mp: Int {
get { return _mp }
}


   - ** 扩展 **
如果在某个特定的应用场景中发现现有的类缺失了某项功能
那么可以通过扩展(extension)的方式现场添加这项功能

extension Point {
var cgPoint: CGPoint {
get { return CGPointMake(CGFloat(x), CGFloat(y)) }
}
}

比如我在画布画贝塞尔曲线的时候,需要把点的坐标转换为CGFloat,就可以现场添加一个函数实现功能。

   -  **运算符重载**
             当我们自己定义的函数也需要进行计算的时候,我们又想直接利用系统的运算符号,那么就可以对系统的符号函数进行运输符重载(+、-、*、/、%、><……都是系统制定的一个函数)

//对小于符号进行重载
func <(one: Student, two: Student) -> Bool {
return one.name < two.name
}

重载后,可以直接调用<符号进行运算:

let stuArray = [
Student(name: "Wang Dachui", age: 24),
Student(name: "Lee Xiaolong", age: 49),
Student(name: "Zhang Nima", age: 18),
Student(name: "Guo Jing", age: 26)
]
// let newArray = stuArray.sort { $0.age > $1.age }
let newArray = stuArray.sort(<)
for stu in newArray {
print("(stu.name): (stu.age)")
}

输出以名字的首字母升序排列:
Guo Jin*: 26
Lee Xiaolon*: 49
Wang Dachu*: 24
Zhang Nim*: 18

* * *
环境果然促人成长,不知几个月后,是怎样的五味杂陈……
###嘿,s  w  i  f  t  e  r

![20160310231228_UduMR.jpeg](http://upload-images.jianshu.io/upload_images/2670532-265efea2086917a7.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容