接下来我再看一下,Swift高级。语法,可能会被认为是简单的、零散的,但是我们学习的重点是,将这些简单的、零散的语法熟练掌握,应用到功能的实现中去。这才是我们想要的。
// main.swift
// Swift-SeniorGrammer
//
// Created by CE on 16/7/8.
// Copyright ? 2016年 vcchou. All rightsreserved.
//
import Foundation
print("Hello, World!")
//一、函数
//1.定义函数
//无参无返回值的函数
func eat() {
print("eating")
}
//函数调用
eat()
//2.定义一个有参数无返回值的函数
//func 函数名(参数名称:参数类型。。。)
func drink(a: Int,b: Int) {
print(a +b)
}
drink(10, b: 20)
//3.定义一个有参数和返回值的函数
//func 函数名(参数名称:参数类型。。。) ->返回值类型
func relax(a: Int,b: Int) ->Int {
return a -b
}
var result1 = relax(30, b: 20)
print(result1)
//4.可以让元组作为函数的返回值
func run(a: Int,b: Int) ->(a1:Int,b1:Int) {
return (a *10,b * 10)
}
var r = run(10, b: 20)
print(r)
print(r.a1) //访问到元组里的具体元素
print(r.b1)
//5.多参量函数
//函数可以有多种不同类型的参数
//函数一
func greet(personName: String) ->String {
return"hello" + personName
}
//函数二
func greetAgain(personName: String) ->String {
return"hello again" + personName
}
//实现多参量函数
func sayHello(personName: String,alreadyGreet: Bool) ->String{
ifalreadyGreet {
return greetAgain(personName)
} else{
return greet(personName)
}
}
print(sayHello("尼古拉斯赵四", alreadyGreet: false))
//6.函数的外部参数
//主要是为了指明每个参数所代表的意义
func login(userName para1: String,password para2: String) {
print("用户名是\(para1),密码是 \(para2)")
}
login(userName: "小明", password: "123")
//忽略参数
func jump(para1: String,_ para2: String) {
print("\(para1) \(para2)")
}
jump("123", "456")
//7.函数的默认参数值
func fly(a: Int,b: Int = 10) ->Int {
return a *b
}
var f = fly(20)
var f1 = fly(20, b: 30)
print(f1)
//8.定义可辨参数的函数(通过...使得函数的参数个数是动态的)
func sum(numbers: Int...) ->Int {
var result =0
for i innumbers {
result += i
}
returnresult
}
var sumResult = sum(1,3,5,2,7,4)
print(sumResult)
//9.函数的常量参数和变量参数
//默认情况下,函数的参数都是let类型
func swim(var a: Int,b: Int) ->Int {
a = a +10
returna
}
var s = swim(10, b: 0)
print(s)
//10.函数的输入输出参数
//使用inout关键字来定义函数的输入输出参数,只有变量才能作为函数的输入输出参数
func change(inout a: Int,inout b: Int) {
let temp =a
a = b
b =temp
}
var c1 = 10
var c2 = 15
change(&c1, b: &c2)
print("c1 is \(c1),c2 is \(c2)")
//11.函数类型的使用
//加法
func add(a:Int,b:Int) ->Int {
return a +b
}
//减法
func sub(a:Int,b:Int) ->Int {
return a -b
}
//共同特点是:(Int,Int) ->Int
//函数类型作为类型标注使用
var res1: (Int,Int) ->Int = add
var finalRes1 = res1(2,3)
print(finalRes1)
//函数类型作为参数类型
func hehe(a: (Int,Int) ->Int,b: Int,c: Int) ->Int {
returna(b,c)
}
var h = hehe(sub, b: 10, c: 30)
print(h)
//函数类型可以作为函数返回类型
func test(a: Int,b: Int) ->(Int,Int) ->Int {
if a + b> 10 {
return sub
} else{
return add
}
}
var t = test(5, b: 4)
print(t(100,200))
//二 闭包
//swift中的闭包是自包含的代码块 可以在代码块中传递和使用 类似oc中的block
//闭包可以捕捉和存储所在上下文任意的常量和变量的引用 即包裹这些常量和变量 在swift中会自动管理捕获的过程中涉及到所有的内存操作
//1.闭包表达式语法
//{(参数:参数类型……)->返回值类型 in
//
// //执行语句
//
//}
//2.sort函数
//是系统提供的一个排序函数 用于对数组中的元素进行排序 并不会修改原来数组
let names = ["Jack","Rose","Xaioming","Zhangsan"];
//比较大小
func prepare(para1:String,para2:String)->Bool{
return para1< para2
}
//实际上试讲自定义的比较函数整个作为参数传递给了sort函数
var newNames = names.sort()
print(newNames)
//3.使用闭包语法写 在oc中用到block的地方 在swift中就是闭包
newNames = names.sort({(para1:String,para2:String)->Boolin
return para1 > para2
})
print(newNames)
//4.根据上下文来推断类型
//在swift中系统可以自动的推断参数和返回值的类型
newNames = names.sort({para1,para2 in
return para1> para2
})
print(newNames)
//5.单表达式闭包隐式返回 参数类型 return都隐藏达到隐式返回的目的 只有单行表达式时可以隐藏
newNames = names.sort({para1,para2 in
para1 >para2
})
print(newNames)
//尾随闭包
//三、枚举
//在c中我们的枚举 将枚举名和一个整型的值相对应 在swift中枚举变得更加灵活 枚举名不再只跟整形值相对应 也不再给每个枚举名提供一个值 如果有值值的类型 可能是字符串 字符 整型 或者 浮点型
//1.定义一个枚举
//使用enum关键字
enum Direction{
//枚举成员值
//case关键字表示新的一行 成员值将被定义
casewest
caseeast
casenorth
casesouth
}
//多个成员值可以定义在同一条语句中 用逗号隔开
enum Aniaml {
casedog,pig,cat,elephant
}
//2.使用枚举值
var direction = Direction.east
//枚举再被初次初始化之后 获取另外的值时 可以直接使用(.)调用
direction = .south
print(direction)
//3.匹配枚举值和swich语句
switch direction {
case.north:
print("north")
case.south:
print("south")
case.west:
print("west")
case.east:
print("east")
}
//四、类和结构体
//1.定义
//类 使用class关键字
class person {
//定义属性
var name =""
var age =0
}
//结构体 是哦用struct关键字
struct student {
//定义属性
var number =20
var grade =5
}
//2.类的实例化
//person类
var per = person()
//给类的属性赋值
per.name = "张三"
per.age = 3
print("姓名:\(per.name),年龄:\(per.age)")
//student的实例化
var stu = student()
//给结构体属性进行赋值
stu.grade = 7
stu.number = 50
print("年级:\(stu.grade),人数:\(stu.number)")
//3.类和结构体的混合编程
struct Hand{
var number =0
}
class Child {
var name =""
var age =0
//将结构作为类型标注 当类中包含自定的类型时 需要将包含定义的类型初始化
var hands:Hand = Hand()
}
//实例化Child
var child = Child()
//属性赋值
child.name = "旺财"
child.age = 12
child.hands.number = 2;
print("小孩\(child.name),今年\(child.age)岁,有\(child.hands.number)只手")
//4.逐一构造器
//结构体具有逐一构造器 但是类没有 因为结构体是值类型 类是引用类型
struct Dog {
var name =""
var age =0
}
//逐一构造器 实例化的同时 对属性进行赋值
var dog = Dog(name: "大黄", age: 3)
//5.值类型
//特点 当赋值给变量或常量或者函数的时候 是通过拷贝的形式 拷贝之后是两个并存独立的文件
var dog1 = dog
print(dog1.name)
dog.name = "小黄"
print(dog.name)
//6.引用类型
//类是引用类型 引用不是独立的 当引用类型给变量或常量或函数复制时 只是做了指针的指向内存中并没有拷贝
class Cat {
var name =""
var age =0
}
var cat = Cat()
cat.name = "小猫"
var cat1 = cat
print(cat1.name)
cat.name = "大猫"
print(cat.name)
print(cat1.name)
//类和结构体的区别
//相同点 1.定义的方式是一样的 2.都有各自的属性 3.实例化的方式一样 4.属性赋值的方式也是一样的
//不同点 1.关键字不同 类class 结构体struct 2.实例化时 结构体有另外的逐一构造器 但类没有 3.结构体是值类型 类是引用类型
//联系 可以将结构体作为类型标注在类中使用
//7.实例方法和类方法的使用
class Tiger {
var name =""
var age =0
//创建实例方法
funceat(){
print("practice makes prfect")
//在实例方法中self表示当前类的对象
self.name = "tiger"
}
//self还可以用来区分属性和形参
funcrun(name:String){
self.name = name
}
//创建类方法可以通过关键字static或class关键字来标明
//在实例方法前面加上一个static或class关键字就成了类方法
static funcbark(){
print("barking")
}
}
//调用类方法和实例方法
//实例化
var tiger = Tiger()
//调用实例化方法:通过对象的调用
tiger.eat()
//调用类方法:通过类名调用
Tiger.bark()
//相同点和不同点
//8.在值类型(结构体)中修改属性
struct student1{
//定义属性
var number =100
var grade =3
//在值类型中定义实例方法 并在实例方法中修改结构体的属性的话 需要使用关键字mutating
mutatingfunc study(){
self.number= 60
print(":\(self.number)")
}
//在实例方法中可以直接对self进行修改
mutatingfunc play(){
//使用逐一构造器
self = student1(number: 30, grade: 8)
print("学生人数:\(self.number),年级:\(self.grade)")
}
}
var stu1 = student1()
stu1.play()
stu1.study()
//9.类的继承
class Car{
var carName= ""
var price =0.0
//可以在父类的实例化方法中添加final关键字 表示 设置此方法不被子类重写
// final funcrun(){
func run(){
print("奔跑吧,皮卡丘")
}
}
//通过类的继承 子类可以继承父类所有的方法和属性
//和oc一样 swift中不许多继承
class AutoCar:Car{
//给子类添加一个新的属性
var factory= "山东蓝翔"
}
var autoCar = AutoCar()
autoCar.carName = "兰博基尼"
autoCar.price = 1.0;
autoCar.run()
class Bicycle:Car{
//如果要在子类中重写父类的方法 需要用override关键字进行表明
overridefunc run() {
print("奔跑吧,呵呵")
}
}
var bicycle = Bicycle()
bicycle.run()
//五 构造函数 (init函数或者初始化函数)
class Bird {
var name =""
var age =0
letwight:Double
//创建构造方法
//构造方法的作用为当类被实例化时 第一个调用的方法
init(){
print("bird")
//swift中的构造方法可以给常量赋值
self.wight = 2.0
}
//带有内部参数的构造方法
init(name:String){
self.name =name
self.wight =3.0
}
//带有外部参数的构造方法
init(namepara1:String,age para2:Int){
self.name = para1
self.age = para2
self.wight = 4.0
}
//隐藏外部参数的构造方法
init(para1:String,_para2:Int){
self.name = para1
self.age = _para2
self.wight = 4.0
}
}
//创建bird对象
var bird1 = Bird.init()
var bird2 = Bird.init(name:"喜鹊")
var bird3 = Bird.init(name:"",age:3)
//var bird4 = Bird.init("麻雀",3)
class FlyBird:Bird{
//在子类中重写父类的构造方法
overrideinit(){
super.init()
}
//析构函数
//只适用于类当一个类的实例被释放后 析构器会被立即调用 析构器使用关键字deinit来标明
deinit{
print("析构器被调用")
}
}
//实例化
var flyBird:FlyBird? = FlyBird()
print(flyBird)
//将flyBird对象置为nil 才会被调用
flyBird = nil
//六 扩展
//使用extension关键字定义扩展
extension Int {
//扩展属性
var a: Int{
//扩展之后进行的操作
return self * self
}
}
//通过点直接调用属性
print(5.a)
extension Bird {
//扩展属性
varbirdColor:String {
return self.name + "是白色的" //self指的还是bird对象
}
//扩展方法
funcsingSong(){
print("\(self.name)在唱歌")
}
}
//通过扩展向父类中提添加的属性和方法 都可以传递给子类
var bird11 = FlyBird()
bird11.name = "鹦鹉"
print(bird11.birdColor)
print(bird11.singSong())