用泛型来交换
func myswap<T>(inout a: T,inout b: T) { let temp = a a = b b = temp } var a = "asfd" var b = "dd" myswap(&a, b: &b) //这里对a和b进行了交换
用泛型来做一个栈
struct Stack<Element> { var containers = [Element]() mutating func push(e: Element) { containers.append(e) } mutating func pop() -> Element { return containers.removeLast() } } var data: Stack<String> = Stack<String>() data.push("ads") //放进栈里去 data.push("as") data.pop() //弹出 data.pop()
扩展时,不需要再指定泛型参数(尖括号里面的内容称之为泛型参数)
extension Stack { var count: Int { return containers.count } } var data2 = Stack<String>() data2.count //Stack是上面的Stack
泛型约束
找出一个数组的下标
func index(arr:[Int],data: Int) ->Int { for (m,n) in arr.enumerate() { if n == data { return m } } return -1 } let array = [1,3,8,2] index(array,data:8) //下标是2
实现一个有Equatable,IA和IB约束的泛型 ,其中Equatable代表的是字符和数字之类的比较
protocol IA{ } protocol IB{ } //接口 func index<T:Equatable where T:IA,T:IB>(arr:[T],data: T) ->Int { for (m,n) in arr.enumerate() { if n == data { return m } } return -1 } extension Int: IA,IB{ } //对Int的拓展 let array2 = [1,3,8,2] index(array2,data:8)
利用泛型实现取出类中的属性 下面取出人中的工资进行累加
class Person{ var salary = 0 } func calc<T:Person>(persons: [T]) ->Int { var total = 0 for p in persons { total += p.salary } return total } //传入一个数组
var p = Person()
p.salary=30
var p2 = Person()
p2.salary=30
let arr=[p,p2]
calc(arr)
用结构来实现泛型 实现栈的功能
////协议的关联类型(associative type) protocol Containter { typealias Element //typealias代表的是某种类型 mutating func push(e: Element) mutating func pop()-> Element } //固定类型的 struct MyStack: Containter{ // typealias Element = Int var containers = [Int]() mutating func push(e: Int) { containers.append(e) } mutating func pop() -> Int { return containers.removeLast() } }
//泛型 struct Stack<Element>: Containter { //按照当前的实现,下面的代码由于类型推断,可以省略 //pealias Element = E var containers = [Element]() mutating func push(e: Element) { containers.append(e) } mutating func pop() -> Element { return containers.removeLast() } } var data: Stack<Int> = Stack() data.push(1) data.push(2) data.pop() data.pop()
typealias代表的是某种类型 用做别名
typealias MyInt = Int let i: MyInt = 3
约束对于拓展
protocol MM { } class MMClass: MM { } protocol NN : MM{ } class NNClass: NN { } //扩展协议时的约束以及与协议关联类型的使用 protocol Container { typealias ItemType } extension Container where ItemType: MM { var b: Int {return 5} } extension Container where ItemType: NN { var b: Int {return 6} } class TestTest: Container { typealias ItemType = MMClass //如果这里改为MMClass,那么aaaa.b输出结构是5 } class TestTest2: Container { typealias ItemType = Int //Int不满足约束 } let aaaa = TestTest() aaaa.b //输出5 //let aaaa = TestTest2() // aaaa.b //报错,因为不满足约束
修饰符
1,private
private访问级别所修饰的属性或者方法只能在当前的Swift源文件里可以访问。
2,internal(默认访问级别,internal修饰符可写可不写)
internal访问级别所修饰的属性或方法在源代码所在的整个模块都可以访问。
如果是框架或者库代码,则在整个框架内部都可以访问,框架由外部代码所引用时,则不可以访问。
如果是App代码,也是在整个App代码,也是在整个App内部可以访问。
3,public
可以被任何人使用
internal class TestModifier { func m() { } } let tu = (TestModifier(),"aa")
//默认是internal
异常
如何创建错误? 如何处理错误?
//创建自己的异常(错误)类 enum PasswordError: ErrorType { case LengthIsNotEnough case Toocomplex } func validatePwd(pwd: String) throws ->Bool { let count = pwd.characters.count if count < 6 { throw PasswordError.LengthIsNotEnough //负者报错 }else if count > 10 { throw PasswordError.Toocomplex //up too } else { return true } } do { print("test") try validatePwd("abcd") //调用时<6 print("fasdfas") } catch PasswordError.LengthIsNotEnough { print("bu gou chang") //处理异常 }catch { print(error) //处理其他异常 } let result = try? validatePwd("abcd") if result == nil { print("diaoyong shi chucuo") } //用可选值来处理 let result2 = try! validatePwd("abcddef") //如果没有异常输出true,反之false
defer有点类似于异常处理中得finally,它也可以用在非异常处理的情况
func m() { //let file = open() print("before") // return defer { print("defer") // close(file) } defer { print("defer2 ") } print("after") } //中的defer是最后输出的 ,但return在前面的话,就不执行了 m()