Swift学习笔记五:扩展协议

这篇博客详细介绍了Swift中的扩展(extension)和协议(protocol)的使用,包括扩展类型属性和方法、协议的声明与遵守,以及闭包(Closure)的详解。此外,还涉及问号和感叹号的用法、泛型编程、错误处理模式do-try-catch、内存管理和懒加载。通过示例代码展示了如何在实践中应用这些概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

六、扩展协议

1.使用扩展(extension)扩展类型的属性

//扩展:就是向一个已有的类、结构体或枚举类型添加新的能力。扩展可以对一个类型添加新的功能,但是不能重写已有的功能。

//关键字:extension

extension Int  //对计算型属性进行扩展

{

    var double: Int

    {

        return self * 2

    }

    var triple: Int

    {

        return self * 3

    }

    var fourfold: Int

    {

        return self * 4

    }

    var half: Double

    {

        return Double(self) / 2.0

    }

}


2.double

2.triple

2.fourfold

2.half



2.使用extension对方法进行扩展

struct Point //定义结构体

{

    var x = 0.0

    var y = 0.0

}


extension Point //对结构体进行扩展

{

    //添加扩展方法

    func distance(anotherPoint: Point) -> Double

    {  //计算与另一个点之间的距离

        let distanceX = anotherPoint.x - self.x

        let distanceY = anotherPoint.y - self.y

        

        return sqrt(distanceX * distanceX + distanceY * distanceY)

    }

}


let startPoint = Point(x: 0.0, y: 0.0)

let endPoint = Point(x: 10.0, y: 10.0)

startPoint.distance(anotherPoint: endPoint)



3.使用协议(protocol)进行方法的声明

//协议规定了用来实现某个功能所需的方法和属性。协议能够被类、结构体等具体实现(或遵守)。

//协议定义了一个方法的蓝图,属性和其它适合特定任务或功能的要求。定义协议与定义类、结构体和枚举非常相似。

protocol Walking

{

    func walk()

}

protocol Eating

{

    func eat()

}

//协议可以遵守另一个协议,将需要遵守的协议名称放在当前协议名称的后方,之间使用冒号进行分隔。

protocol Fighting: Walking

{

    func fight()

}

//该类遵循两个协议,类名和协议名称之间仍然使用冒号进行分隔,而协议名称之间则使用逗号进行分隔。

class Animal : Fighting, Eating

{

    var name = "Bird"

    var age = 1

    var damage = 10

    

    func fight()

    {

        print("Fighting very hard!")

    }

    func eat()

    {

        print("Happily eating!")

    }

    func walk()

    {

        print("Working gracefully!")

    }

    func say()

    {

        print("I'm a dove of peace!")

    }

}


var animal = Animal()

animal.damage

animal.fight()

animal.eat()

animal.walk()

animal.say()


extension Animal //对类进行扩展

{

    var weight: Double

    {

        get{return 15.0}

    }

    func getWeight()-> Double

    {

        return 45.6

    }

}


var secondAnimal = Animal()

secondAnimal.say()

secondAnimal.getWeight()



4.问号?和感叹号!的用法解析

//系统不会自动给变量设置初始值,也就是说变量不会有默认值,所以在使用变量之前需要进行初始化。

//使用泛型定义一个Optional类型的变量,从右侧可以看出,它是空值nil,没有初始化值。Optional其实是个枚举,里面有None和Some两种类型,用来包装原始值。

//var password: Optional<Any>

//var password: String?


//var password: String

//print(password.characters.count)


//第一个问号:作用是声明一个Optional变量;第二个问号:作用是在对Optional值操作时,判断是否可以响应后面的操作。

//var password: String?

//print(password?.characters.count)


//双问号(??):当前面的代码无法执行时,就采用双问号后面的值

//var password: String?

//print(password?.characters.count ?? 0)


//感叹号(!):对Optional值进行拆包(从枚举里面取出来原始值)

//var password: String?

//print(password!.characters.count)


var password: String?

password = "123456"

//print(password!.characters.count)

print(password?.characters.count ?? 0)


//传统的空值判断,通常要使用if语句,代码量比较大,而使用问号和感叹号,则可以很简洁的进行空值判断。

class Pet

{

    var name : String?

}


class Person

{

    var name : String?

    var pet : Pet?

}


let person = Person()

person.pet

person.pet?.name


person.pet = Pet()

person.pet

person.pet?.name


person.pet?.name = "Bird"

person.pet?.name



5.Swift中的闭包(Closure)详解

var sum:(Int,Int) ->Int = //等号下方的大括号:是用来实用一个函数功能的代码块

{

    //两行代码:第一行代码:用来声明函数代码块的参数和返回值信息;第二行代码:对参数操作,放在in的下方

    (a:Int, b:Int)->Int in

    return a + b

}

sum(1, 1)


//和上方功能相同

func sum(a:Int, b:Int)->Int

{

    return a + b

}

sum(1, 1)


//使用闭包声明一个函数类型的变量时,可以省略对变量类型的定义,系统会自动推断出它的类型

var anotherSum =

{

    (a:Int, b:Int)->Int in

    return a + b

}


//等号右侧,省略了参数声明的闭包语句

var thirdSum: (Int, Int) -> Int = {return $0 + $1}

thirdSum(1, 1)


//使用$0和$1表示第一个参数和第二个参数,并且省略了return操作符

var fourthSum: (Int, Int) -> Int = {$0 + $1}

fourthSum(1, 1)


let array = [4, 2, 3].sorted(){ $0 < $1 }

array


//闭包语句通常和方法声明配合使用,但是闭包语句通常放在最后一个参数的位置。

func subTowNumbers(number1: Int, number2: Int, method: (Int, Int) -> Int) -> Int

{

    return method(number1, number2)

}


subTowNumbers(number1: 1, number2: 1, method: {

    (a:Int, b:Int) -> Int in

    return a + b

})


subTowNumbers(number1: 1, number2: 1, method: sum)

//用+代替求和闭包

subTowNumbers(number1: 1, number2: 1, method: + )

subTowNumbers(number1: 2, number2: 3, method: * )

subTowNumbers(number1: 2, number2: 3){ $0 * $1 }



6.Swift语言中的泛型编程

//泛型是另一个可以使编码更加简单、快捷的方式,可以理解为泛指所有类型。

//将一个整型数组合并到另一个整型数组

func appendToIntArray(array:[Int], toArray:inout [Int])

{

    for item in array

    {

        toArray.append(item)

    }

}


var array = [1, 2, 3]

appendToIntArray(array: [4, 5, 6], toArray: &array)


func appendToStringArray(array:[String], toArray:inout [String])

{

    for item in array

    {

        toArray.append(item)

    }

}


var arrayString = ["Objective-C", "Java"]

appendToStringArray(array: ["Swift", "Python"], toArray: &arrayString)


//在函数名称右侧使用尖括号<>声明一个泛型,大写T表示任意的类型

func appendToGenericArray<T>(array:[T], toArray:inout [T])

{

    for item in array

    {

        toArray.append(item)

    }

}


var anotherIntArray = [1, 2, 3]

appendToGenericArray(array: [4, 5, 6], toArray: &anotherIntArray)


var anotherStringArray = ["Objective-C", "Java"]

appendToGenericArray(array: ["Swift", "Python"], toArray: &anotherStringArray)


var anotherCGPointArray = [CGPoint(x:0, y:0), CGPoint(x:10, y:10) ]

appendToGenericArray(array: [CGPoint(x:20, y:20), CGPoint(x:30, y:30)], toArray: &anotherCGPointArray)



7.Swift的do-try-catch错误处理模式

enum ErrorType: Error

{

    case invalidProduct

    case insufficientCoins(coinsNeeded: Int)

    case outOfStock

}


///商品

struct Product

{

    var price: Int

    var count: Int

}


//当前总金额

var totalCoins = 20


//商店

class Shop

{

    var products =

        [

            "Pudding": Product(price: 12, count: 7),

            "Donut": Product(price: 10, count: 4),

            "Cheesepuff": Product(price: 7, count: 11)

    ]

    

    func sell(productName: String) throws

    {

        //guard-let和if-let类似,都是根据其后的表达式的布尔值,决定下一步做什么。

        guard let product = products[productName] else

        {

            throw ErrorType.invalidProduct

        }

        //通过throw关键词,抛出异常,即提示错误的具体信息。当需要在函数或者方法里抛出异常,使用throw就可以。

        guard product.count > 0 else

        {

            throw ErrorType.outOfStock

        }

        

        guard product.price <= totalCoins else

        {

            throw ErrorType.insufficientCoins(coinsNeeded: product.price - totalCoins)

        }

        

        totalCoins -= product.price

        

        var newItem = product

        newItem.count -= 1

        products[productName] = newItem

        

        print(">>>>>> \(productName)")

    }

}


var shop = Shop()

//do-catch语句就是尝试做一件事情,如果失败则捕获出现的错误。

do

{

    //    try shop.sell(productName: "Apple")

    try shop.sell(productName: "Pudding")

    try shop.sell(productName: "Pudding")

}

catch ErrorType.invalidProduct

{

    print("Invalid product.")

}

catch ErrorType.outOfStock

{

    print("Out of Stock.")

}

catch ErrorType.insufficientCoins(let coinsNeeded)

{

    print("Need an additional \(coinsNeeded) coin(s).")

}



8.实例的引用特征和Swift的内存管理

//Swift使用自动引用计数,跟踪并管理应用分配的内存。

class Person

{

    var name : String

    

    init(name: String)

    {

        self.name = name

    }

    deinit

    {

        print("-------- deinit")

    }

}


var person :Person? = Person(name: "Bill")

var person2 = person

var person3 = person


person = nil

person2 = nil

person3 = nil



9.实例的交叉引用和弱引用(weak)

class People

{

    var name : String

    var pet : Pet?

    

    init(name:String)

    {

        self.name = name

        print("People is initialized.")

    }

    

    deinit

    {

        print("People is deinitialized.")

    }

}


class Pet

{

    var name : String

    weak var master : People? //weak关键字,进行弱引用

    

    init(name:String)

    {

        self.name = name

        print("Pet is initialized.")

    }

    

    deinit

    {

        print("Pet is deinitialized.")

    }

}


var master:People?

var dog:Pet?


master = People(name: "Jerry")

dog = Pet(name: "Dog")


master!.pet = dog

dog!.master = master


master = nil

dog = nil



10.Swift的懒加载(lazy initialization)使用解析

//懒加载:用到时候才会开辟内存空间,多次使用只会加载一次,关键词:lazy

class Demo

{

    var url:NSString

    lazy var completeURL:NSString =

        {

            [unowned self] in

            if self.url.hasPrefix("http://")

            {

                return self.url

            }

            else

            {

                return "http://\(self.url)" as NSString

            }

            }()

    

    init(url:NSString)

    {

        self.url = url

    }

}


let demo = Demo(url: "www.coolketang.com")

demo.url

demo

demo.completeURL

demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值