简单的
// protocol // 搞不懂为嘛不使用Flier<T>,而要多使用一个关键字associatedtype // 注: associatedtype是swift2.2新引入的关键字,先前为typealias protocol Flier { associatedtype T func flyWith(f: T) func mateWith(f: T) func shitWith(f: Self) //Self表示将要实现这个接口的那个`类`的类型 } // 实现接口 class Bird: Flier { func flyWith(f: String) {} func mateWith(f: String) {} func shitWith(f: Bird) {} } // 函数 func takeAndReturn<T>(t: T) -> T { return t } takeAndReturn("hello") takeANdReturn(2) // 结构体 struct HolderOfTwoSame<T> { var v1: T var v2: T } HolderOfTwoSame(v1: "hello",v2: "world") // 类 class Animal<T> { func playWith(t: T) { print("I am playing with: \(t)") } } // 继承自指定了具体的泛型类型的Animal class Dog: Animal<String> {} // 继承自泛型的Animal class AnotherDog<T>: Animal<T> { override func playWith(t: T) { print("I played with: \(t)") } } var animal = Animal<Int>() animal.playWith(2) var d = Dog(); d.playWith("only string allowed here") var dd = AnotherDog<String>() dd.playWith("xiaohua")
多个泛型参数
// protocol // 搞不懂为嘛不使用Flier<A,B>,而要多使用一个关键字associatedtype? protocol Flier { associatedtype A associatedtype B func flyWith(f: A) func mateWith(f: B) func shitWith(f: Self) //Self表示将要实现这个接口的那个`类`的类型 } class Bird: Flier { func flyWith(f: String) {} func mateWith(f: String) {} func shitWith(f: Bird) {} } // func func takeAndReturn<A,B>(v1: A,v2: B) -> (A,B) { return (v1,v2) } takeAndReturn("hello",v2: 2) // struct struct HolderOfTwoType<A,B> { var v1: A var v2: B } HolderOfTwoType(v1: "hello",v2: "world") // class class Animal<A,B> { func playWith(t: A,and: B) { print("I am playing with: \(t) and \(and)") } } class Dog: Animal<String,Int> {} var animal = Animal<Int,String>() animal.playWith(2,and: "Alice") var d = Dog(); d.playWith("only string allowed here",and: 3)
带类型约束的(protocol)
// 第一版 // protocol protocol Flier { func flyWith(f: Flier) } class Bird: Flier { // 这里只能和protocol保持一致,声明为Flier,// 声明为Bird就会报错,(怎么能在这里定义成Bird,见下面) func flyWith(f: Flier) {} } class ButterFly: Flier{ func flyWith(f: Flier){} } var b1 = Bird() var b2 = ButterFly() b1.flyWith(b2) // 以下是第二版 // protocol protocol SuperFlier {} protocol Flier: SuperFlier { // error: type may not reference itself as a requirement // associatedtype T: Flier associatedtype T: SuperFlier // 可以用一个类型为Flier的占位符放在这里 // 但是蛋疼的是,不能使用接口自身做为占位符 // 所以这里定义了一个什么都不干的SuperFlier以此满足compiler的要求 func flyWith(f: T) } class Bird: Flier { // 然后就可以在这里使用Bird func flyWith(f: Bird) {} } var b1 = Bird() b1.flyWith(b1)
带类型约束的(func)
// 出现了Self或associatedtype关键字的protocol叫做generic protocol // generic protocol不能直接放在参数列表中,只能做为类型约束(出现在尖括号里) protocol Flier { associatedtype T func flyWith(f: T) } // 注意这里的Bird并没有实现该generic protocol,只是使用了(依赖)Flier class Bird{ // error: protocol 'Flier' can only be used as a generic constraint because it has Self or associated type requirements //func flyWith(f: Flier) {} // 上面这行代码出错,应该改为 func flyWith<T: Flier>(f: T) {} } // eg2: 函数体中的小于号要求这里的泛型参数必须是Comparable类型的 func myMin<T: Comparable>(things: T...) -> T { var minimum = things[0] for ix in 1..<things.count { if things[ix] < minimum { minimum = things[ix] } } return minimum }
待续
阅读[What do you really know about typealias and associatedtype?]
在实现中指定泛型类型的几种方式
// 接口如下 protocol IAnimal { associatedtype T = Double // 其中 = Double是指定它的默认实现类型,可以去掉 func playWith(t: T) } class Cat : IAnimal { // 1. 通过typealias指定associatedtype的具体类型 typealias T = String func playWith(t: T) { print("I played with: \(t)") } } // 2. 通过尖括号指定associatedtype的具体类型 class AnotherCat<T> : IAnimal { func playWith(t: T) { print("I played with: \(t)") } } // 3. 通过尖括号指定associatedtype的具体类型(带类型约束) class YetAnotherCat<T: IAnimal> : IAnimal { func playWith(t: T) { print("I played with: \(t)") } } var cat1 = Cat() cat1.playWith("meow") var cat2 = AnotherCat<Int>() cat2.playWith(2) var cat3 = YetAnotherCat<Cat>() cat3.playWith(cat1)
待续
原文链接:https://www.f2er.com/swift/323660.html