SWIFT学习第二周

一.集合

1.集合的基本定义:

var a : Set = [1,2,3,4,2,3]

如果你打印出来,并不会有相同的元素出现

print(a)

结果就会是:[1,2,3,4]

2.遍历集合

for x in a{
    print(x)
    }

遍历出来也不会有相同的元素出现

3.添加元素和删除元素

就一上面的a数组为例,添加元素:

a.insert(9)

同理删除元素:

a.remove(2)

4.并集,交集,差集,判断子集

仍然以还是那个面的a集合为例

var b:Set = [2,3,4,7,9,11]
print(a.intersect(b))//并集
print(a.union(b))//交集
print(a.subtract(b))//差集(a有而b没有的元素)
print(b.isSubsetOf(a))//判断子集

二.字典(Dictionaries)

1.定义和组成:

存放键值对组合的容器,字典中的每一个元素都是由两部分构成的,冒号前面是键,冒号后面是值

var dict = ["abacus":"算盘","abnormal":"异常的","hello":"你好","good":"你好"]

通过键获取对应的值(可空类型,因为给的键有可能没有与之对应的值):key-->value

####2.在字典中加键,删除键,修改元素
print(dict["hello"]!)
print(dict["ashdg"])
dict["shit"] = "狗屎" //在字典里面加一个键
dict.removeValueForKey("hello")//删除一个键
dict["hello"] = nil//这样也是阔以的
//修改里面的元素
dict["shit"] = "牛粪"

3.遍历字典中的值,键,值和键

遍历字典中所有的值

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

遍历字典中所有的键

for key in dict.keys{
    print("\(key)--->\(dict[key])")
}

遍历字典中所有的键和对应的值

for (key,value) in dict{
    print("\(key)--->\(value)")
}

三.函数

1.函数的定义

独立的,能重复的使用的功能模块。
基本形式:func 函数名 (参数列表) -> 返回元素{函数的执行体}。
函数名 (外部参数名 内部参数名:类型,外部参数名,内部参数名:类型)
注:可以使用_来作为外部参数名表示省略外部参数名。

func sayHello( personName: String,
    alreadyGreeted:Bool = false) ->String{
    //let greeting = "Hello, " + personName + "!"
    //如果函数的返回类型不是void,那么函数中一定有return语句
    //return greeting
    //personName:"王小锤"   会产生编译错误
    if alreadyGreeted{
        return"怎么又是你, " + personName + "!"
    }
    else{
        return "你好," + personName + "!"
    }
   return "Hello, " + personName + "!"
}
//调用函数,写出函数的名字,加上参数的值就可以了


print(sayHello("王大锤", alreadyGreeted: true))
let str = (sayHello("蒋渣渣"))//可以给参数指定默认值,如果函数的使用的时候没有给参数辅值就直接使用默认值,就像这里的false

2.函数的基本使用方法

func min1(x: Int,b y: Int) -> Int{
    return x < y ? x : y
}
//调用时要用外部参数名b,如果不写b,内外参数名一致的
print(min1( 3,b: 5))
func sum(nums: Int...) -> Int{//可变参数列表,参数的数量可以为任意个...
    var total = 0
    for num in nums {
        total += num
    }
    return total
}
print(sum())
print(sum(999))
print(sum(1,2,3,5,6))
//可以使用元组(tuple)来让一个函数返回多个数据
func minMax(array: [Int]) -> (min: Int, max: Int)? {
    if array.count == 0 {
        return nil
    }
    var currentMin = array[0]
    var currentMax = array[0]
    for value in array[1.. currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
    }if let b =     minMax([4823,34,849,8440,9498,]){

print(b.min)   //print(b.0)
print(b.max)   //print(b.1)
}
else{
    print("数组中没有元素!!!")
}

func swap(inout a: Int,inout b: Int) -> Void{
//    let temp = a
//    a = b
//    b = temp
    (a,b) = (b,a)
}
//函数调用的传参都是传值
var a = 5, b = 10
swap(&a, &b)
print("a = \(b)")
print("b = \(a)")

func createX(inout x : Int){//inout - 输入输出参数(不仅将数据传入函数中还要从函数中取出数据)
    x = 1000
}
var x = 1
createX(&x)
print(x)

3.相关练习:

练习一:设计一个函数传入两个整数m和n(n>m),计算m加到n的和

func sum(m:Int,_ n:Int) -> Int{
    let (a,b) = m > n ? (n,m) : (m,n)
        var value = 0
        for i in a...b{
           value +=  i
        }
    return value
    }
print(sum(1,100)

练习二:设计一个函数输入三条变得长度,判断能不能构成三角形

func triangle(a: Double,_ b:Double,_ c:Double ) ->Bool{
    assert(a > 0 && b > 0 && c > 0,"三角形的边长必须大于0")
    if a + b > c && a - b < c {
        return true
    }
    else{
        return false
    }
}
print(triangle(3.0,2.0,5.0))

练习三:
设计一个函数传入年月日返回该日期是这一年的第几天

func daysofYear(year: Int,month: Int,day: Int) ->Int{
    var day1 = 0
    var array = [31,28,31,30,31,30,31,31,30,31,31,30]
    if year % 4 == 0 && year % 100 != 0 || year % 400 == 0 {
        array[1] = 29
    }
    for i in 0..

练习四
设计一个函数计算组合数c(m,n) = m!/n!/(m-n)!

//求阶乘
func factorial(n: Int) -> Double{
    var val = 1.0
    var i = 2
    while i <= n{
        val *= Double(i)
        i += 1
    }
    return 0.0
}
func combine(m:Int,n:Int) -> Double{
    assert(m >= n,"m必须大于等于n")//断言
    var b:Double
    b = factorial(m) / factorial(n) / factorial(m-n)
    return b
}
func factorial(a: Int) -> Double{
    var val = 1.0
    var i = 1                  //函数的递归调用(一个函数直接或者间接的调用自身)
                               //1.递归公式 2.收敛条件
    while i <= a{             //if n == 0 || n == 1{
                            //return 1
                            //  }
    val *= Double(i)     //  return Double(n) * f (n - 1)
        i += 1
    }
    return val
}
print(combine(3, n: 2))

4.函数的扩展(函数也可以作为参数使用,闭包)

func sum(a: Int,_ b: Int) -> Int {
    return a + b
}
func mul(a: Int,_ b: Int) -> Int{
    return a * b
}
//var fn: (Int,Int) ->Int = sum
//fn(2,3)
//fn = mul
//fn(2,3)
func foo(array: [Int],fn: (Int,Int) ->Int) -> Int {
    var sum = array[0]
    for x in array[1..
// 1.所有自定义的(Int,Int)-> Int类型的函数
print(foo(a, fn: sum))
// 2.传入二元运算符:+—*/%(因为运算符也是函数)
print(foo(a, fn: +))
// 3.传入匿名函数(闭包)
// 3.1 完整的闭包写法
print(foo(a, fn: { (a: Int,b: Int) -> Int in
    return a + b
}))
// 3.2 省略掉类型和不必要的括号
print(foo(a, fn: {a, b in a+b}))
// 3.3 省略参数名
print(foo(a, fn: {$0 + $1}))
// 3.4 尾随闭包
print(foo(a) {$0 + $1})
print(foo(a) { (a, b) -> Int in
    return a + b
})

var array = ["game","abacus","hello","cat","good","dislike"]
array.sortInPlace(>)
array.sortInPlace({$0 > $1})
array.sortInPlace() {$0 > $1}
array.sortInPlace {$0 > $1}

4.尾随闭包

如果函数的最后一个参数是闭包可以写成尾随闭包的形式
也就是将闭包放到函数参数的圆括号外面写在一堆花括号中
如果函数后面有尾随闭包且函数的圆括号中没有参数
那么函数的圆括号也可以省略(仅限于有尾随闭包的场景)

array.sortInPlace {
    if $0.characters.count == $1.characters.count{
          return $0 < $1
    }
   return $0.characters.count < $1.characters.count
}
print(array)

5.补充

.数组的过滤,映射,缩减

let array = [37,23,49,93,54,81,29]
1.过滤

let newArray = array.filter {$0 > 50}
print(newArray)
let newArray1 = array.filter {$0 % 2 == 0}

print(newArray1)

2.映射

let newArray2 = array.map { $0 * $0}
 print(newArray2)
let newArray5 = array.map{sqrt((Double)($0))}
print(newArray5)

3.缩减

let result1 = array.reduce(0, combine: +)
print(result1)
let result2 = array.reduce(1, combine: *)
print(result2)

let result3 = array.reduce(array[0]){
    $1 > $0 ? $1 : $0
}
print(result3)
let strArray = ["I","love","you"]
let result4 = strArray.reduce(""){
    $0 + " " + $1
}
print(result4)

四.面向对象

1.面向对象的几个步骤:

步骤一:定义类(如果你要用的类苹果都没有提供出来,就执行第二步)

//定义类就可以创建出新的类型
//学生类
class Student{   //首字母都要大写
    //变量定义到类的外面就叫变量 - variable
    //变量定义到类的里面就叫属性 - property
    //数据抽象 - 找到和学生相关的属性(找名词)
    var name: String
    var age: Int
    //初始化方法(构造方法/构造器) - 创建对象要使用的方法 - constructor
    init(name: String,age: Int){
        self.name = name
        self.age = age
    }
    //行为抽象 - 找到和学生相关的方法(找动词)
    func eat(foodName: String) -> Void{
        print("\(name)正在吃饭.")
    }
    func study(courseName: String){
        print("\(name)正在学习\(courseName).")
    }
    func watchJapaneseAV(){
        if age >= 18{
            print("\(name)正在观看岛国爱情动作片.")
        }
        else{
            print("亲爱的\(name)快去看《熊出没》吧!")
        }
    }
}
//写到类里面的函数叫方法 - method,写到类的里面一般就叫函数 - function

步骤二:创建对象(调用初始化方法

let stu1 = Student(name: "王景亮", age: 25)

步骤三:给对象发消息(通过给对象那个发消息来解决问题)

stu1.eat("")
stu1.study("Swift程序设计")
stu1.watchJapaneseAV()

2.类的举例

//枚举类型:枚举是定义符号常量的最佳方式
          符号常量总是优先于普通常量
enum Gender {
    case Male,Female
}
class Dog {
    var nickname : String
    var sex: Gender
    init(nickname: String, sex: Gender){
        self.nickname = nickname
        self.sex = sex
    }
    func bark(){
        print("\(nickname): 汪汪汪。。")
    }
    func mate(other: Dog) -> Bool{
        if sex != other.sex{
            print("\(nickname)和\(other.nickname)正在交配。。。")
            return true
        }
        else{
            return false
        }
    }
}
let dog1 = Dog(nickname: "旺财", sex: .Male)
let dog2 = Dog(nickname: "大黄", sex: .Female)
dog1.bark()
dog2.bark()
if dog1.mate(dog2){
    print("交配成功!")
}
else{
    print("交配失败!")
}

3.一般我们把类写成一个文件,以便我们调用和管理

1.线的类:

class Line {
    var start : Point
    var end : Point
    init(start:Point,end:Point){
        self.start = start
        self.end = end
    }
    func intersects(other: Line) ->Bool{
        return false
    }
    var length : Double{
        get {return start.distanceTo(end) }
    }
}

2.三角形类:

class Triangle {
    var va: Point
    var vb: Point
    var vc: Point
    init(va:Point,vb:Point,vc:Point){
        self.va = va
        self.vb = vb
        self.vc = vc
    }

    var perimeter : Double{
        get {
            let ab = va.distanceTo(vb)
            let bc = vb.distanceTo(vc)
            let ac = vc.distanceTo(va)
            return ab + bc + ac
        }
    }
    var area : Double{
        get {
            let ab = va.distanceTo(vb)
            let bc = vb.distanceTo(vc)
            let ac = vc.distanceTo(va)
            let halfp = perimeter / 2
            return  sqrt(halfp * (halfp - ab) * (halfp - bc) * (halfp - ac))
        }
    }
}

3.点类

class Point {
    var x: Double
    var y: Double
    //我们可以在一个类中定义多个初始化方法
    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
    }
    func moveTo(m: Double,n: Double){
        self.x = m
        self.y = n
    }
    func distanceTo(other: Point) -> Double{
        let x1 = other.x - x
        let y1 = other.y - y
        return sqrt(x1 * x1 + y1 * y1)
    }
}

4.计算属性与访问修饰符

-找名词和动词。名词会成为类或者类中的属性,动词会成为类中的方法

 // 数据抽象
  //行为抽象
 // 初始化方法
 //访问修饰符
 //public (公开)
 //internal(内部的) - 默认
 //private (私有)
public class Circle {
    //存储属性(保存和元相关的数据的属性)
     var radius: Double
    init(radius: Double){
        self.radius = radius
    }
    //通常获得某个计算出的值得方法,通常都写成计算属性
     //computational property
    //计算属性(通过对存储属性做运算得到的属性)
    var perimeter: Double {
        //圆的周长是一个只读属性
        //所以此处只有get{}没有set{}
        get { return 2 * M_PI * radius }
    }
    var area : Double{
        get { return  M_PI * radius * radius }
    }
}

5.重载运算符

有时在我们写程序过程中两个对象不能直接的做 + - * / % 等等的运算,我们需要将运算符根据我们的需要重载(其实这几种常用的运算符也是一种函数)

func <(one: Student,two: Student) -> Bool {
    return one.age < two.age
}
//运算符的重载
let stuArray = [
    Student(name: "wangjingliang", age: 21),
    Student(name: "lee xiaolong", age: 49),
    Student(name: "zhang nima", age: 18),
    Student(name: "Guo jing", age: 26)
]
let newArray = stuArray.sort(<)

for stu in newArray{
    print("\(stu.name): \(stu.age)")
}

五.继承和多肽

继承:主要是指,在父类存在的情况下,子类能够继承父类的相关属性。
父类:

enum Gender{
    case Male
    case Female
}

class Pet {
    var nickname : String
    var gender : Gender
    var age : Int
    init(nickname : String ,gender : Gender,age : Int){
        self.nickname = nickname
        self.gender = gender
        self.age = age
    }
    func eat(){
        print("\(nickname)正在吃吃吃")
    }

    func play(){
        print("\(nickname)正在玩耍")
    }
        func shout(){
        print("\(nickname)发出了叫声")
    }
}

一个子类:

class Cat:  Pet{
    var hairColor: String?

    override func shout() {
//override表示重写,父类有的方法子类可以重新实现这个过程叫方法的重写,需要在方法前添加override关键字,重写有时也被称为,置换,覆盖,覆写。。。。
        print("\(nickname)正在喵喵喵。。。")
    }

    override func play() {
        super.play()            // 调用父类的方法
        print("\(nickname)正在玩毛线")
    }
    
    func catchmouse(){
        print("\(nickname)正在抓耗子")
    }

}

第二个子类:

class Dog : Pet {
    var isLarge : Bool
    
    init(nickname: String,gender: Gender,age: Int,isLarge: Bool){
        self.isLarge = isLarge
        super.init(nickname: nickname, gender: gender, age: age)
        
    }
    
    
    override func shout() {
        print("\(nickname)正在汪汪汪,,,")
    }
    
    override func play() {
        print("\(nickname)正在玩球球")
    }
    
    override func eat() {
        print("\(nickname)正在吃粑粑")
    }
}

let petsArray = [
    Cat(nickname:"加菲",gender: .Female, age:2),
    Dog(nickname: "小王", gender: .Male, age: 3, isLarge: true),
    Dog(nickname: "王景亮", gender: .Male, age: 5, isLarge: false),
    Monkey(nickname: "小芳",gender: .Male, age: 10)
]
for pet in petsArray{
//pet.eat()
//   pet.play()
    // 同样的对象类型(Pet类型)接受相同的消息(调用相同的方法)
    //但是做了不同的事情,这就是多肽(polymorphism)
    // 1.方法的重写:子类在继承父类的过程中,对父类已有的方法进行重写,而且不同的子类给出不同的实现版本
    //2.对象造型:将子类对象当成父类型来使用
    //可以通过if+as?将父类型安全的转换成子类型然后再调用子类特有的方法
    pet.shout()
    if let dog = pet as? Dog{
        dog.eat()
    }
    else if let cat = pet as? Cat{
        cat.catchmouse()
    }
}

六.总结

        这是小编的swift学习的烧脑的第二周,总的来说还是收获颇多,第一次这么认真的学习一种编程语言,但是很多地方还是想不明白,我还会努力的,希望在接下来的日子里做得更好,如果你觉得以上内容对你有所帮助,不妨动一下您的贵手,
点一波关注,后面我还会继续写一些这方面的学习心得。有什么不足的地方,
欢迎指出,你们的建议将是对我最大的支持,谢谢!

你可能感兴趣的:(SWIFT学习第二周)