目录
泛型使用
/// 一、泛型使用
func genericsUse() -> Void {
//1、 相同逻辑不同类型 需要写两个方法
do{
print("--------1---------")
var num1 = 10
var num2 = 20
func swapInt(_ num1:inout Int, _ num2:inout Int){
let temp = num1
num1 = num2
num2 = temp
}
swapInt(&num1,&num2)
print(num1,num2)
func swapDouble(_ num1:inout Double,_ num2:inout Double){
let temp = num1
num1 = num2
num2 = temp
}
var dnum1 = 10.0
var dnum2 = 20.0
swapDouble(&dnum1, &dnum2)
print(dnum1,dnum2)
}
//2、解决方式一:any
do{
print("--------2---------")
func swapAny(_ item1:inout Any,_ item2:inout Any){
let temp = item1
item1 = item2
item2 = temp
}
var int1:Any = 10
var int2:Any = 20
swapAny(&int1, &int2)
print(int1,int2)
var float1:Any = 10.0
var float2:Any = 20.0
swapAny(&float1, &float2)
print(float1,float2)
var str1:Any = "hehe"
var str2:Any = "haha"
swapAny(&str1, &str2)
print(str1,str2)
}
//3、解决方式二:generic 泛型
do{
print("--------3---------")
func swapGeneric<T>(_ num1:inout T,_ num2:inout T){
let temt = num1
num1 = num2
num2 = temt
}
var int1 = 10
var int2 = 20
swapGeneric(&int1, &int2)
print(int1,int2)
var float1 = 10.0
var float2 = 20.0
swapGeneric(&float1, &float2)
print(float1,float2)
var str1 = "hehe"
var str2 = "haha"
swapGeneric(&str1, &str2)
print(str1,str2)
// let fn = swapGeneric//报错 Generic parameter 'T' could not be inferred
let fn:(inout String,inout String)->Void = swapGeneric
print(fn(&str1, &str2))
//泛型可以有多个
func test<T1, T2>(_ t1: T1, _ t2: T2) {}
var fnt: (Int, Double) -> () = test
}
}
泛型使用2
/// 二、泛型使用2
func genericsUse2() -> Void {
class Stack{
var elements = [Int]()
func push(_ element:Int) {
elements.append(element)
}
func pop() -> Int {
elements.removeLast()
}
func top() -> Int {
elements.last!
}
func size() ->Int {
elements.count
}
}
let stack = Stack()
//泛型可以将类型参数化
//提高代码复用率,减少代码量
class Stack2<E>{
var elements = [E]()
func push(_ element:E) {
elements.append(element)
}
func pop() -> E {
elements.removeLast()
}
func top() -> E {
elements.last!
}
func size() ->Int {
elements.count
}
}
let stack2 = Stack2<Int>()
stack2.push(1)
stack2.push(2)
print(stack2.pop())
print(stack2.top())
print(stack2.size())
struct Stack3<E> {
var elements = [E]()
mutating func push(_ element: E) { elements.append(element) }
mutating func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}
enum Score<T>{
case point(T)
case grade(String)
}
let score0 = Score<Int>.point(100)
let score1 = Score.point(99)
let score2 = Score.point(99.5)
// let score3 = Score<Int>.point(99.5)//报错
// let score4 = Score.grade("A")//报错
let score5 = Score<Int>.grade("A")
print(score0,score1,score2,score5)
//继承香瓜
class SubStack<E> : Stack2<E> {}
}
关联类型使用
/// 三、关联类型使用
//关联类型的作用:给协议中用到的类型定义一个占位名称
//协议中可以拥有多个关联类型
protocol Stackable {
associatedtype Element // 关联类型
// associatedtype Element2 // 关联类型
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}
protocol Runnable2 { }
protocol Stackable2 {
associatedtype Element:Equatable
}
func accociatedTypeUse() -> Void {
//1、给关联类型设定真实类型
do{
class StringStack : Stackable {
typealias Element = String
var elements = [String]()
func push(_ element: String) { elements.append(element) }
func pop() -> String { elements.removeLast() }
func top() -> String { elements.last! }
func size() -> Int { elements.count }
}
let ss = StringStack()
ss.push("Jack")
ss.push("Rose")
}
//2、给关联类型设定泛型
do{
class Stack<E> : Stackable {
// typealias Element = E
var elements = [E]()
func push(_ element: E) {
elements.append(element)
}
func pop() -> E { elements.removeLast() }
func top() -> E { elements.last! }
func size() -> Int { elements.count }
}
}
//3、类型约束
do{
class Person { }
func swapValues<T : Person & Runnable2>(_ a: inout T, _ b: inout T) {
(a, b) = (b, a)
}
class Stack2<E : Equatable> : Stackable2 {
typealias Element = E
}
func equal<S1: Stackable2, S2: Stackable2>(_ s1: S1, _ s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
return false
}
let stack1 = Stack2<Int>()
let stack2 = Stack2<Int>()
let stack3 = Stack2<String>()
print(equal(stack1, stack2))
// print(equal(stack1, stack3))//报错 S1.Element == S2.Element 条件不满足 一个 Int 一个 String
}
}
some的使用
/// 四、some的使用
protocol Runnable4 {
associatedtype Speed
}
func someUse(){
class Car:Runnable4{
typealias Speed = Int
}
class Person:Runnable4{
typealias Speed = Double
}
//返回一个遵守 Runable4 的类型
//如果 Runable4 有关联类型 这么写会报错
// func get(_ type:Int)->Runnable4{
// if type == 0 {
// return Car()
// }
// return Person()
// }
//解决方法一:泛型
do{
func get<T:Runnable4>(_ type:Int)->T{
if type == 0 {
return Car() as! T
}
return Person() as! T
}
let car:Car = get(0)
let person:Person = get(1)
}
//解决方案2:使用some关键字声明一个不透明类型
//some限制只能返回一种类型
do{
// func get(_ type: Int) -> some Runnable4 {
// Car()
// }
// var r1 = get(0)
// var r2 = get(1)
//some除了用在返回值类型上,一般还可以用在属性类型上
// class Dog : Runnable4 { typealias Speed = Double }
//
// class Person {
// var pet: some Runnable4 {
// return Dog()
// }
// }
}
}
行者常至,为者常成!