swift泛型

前端之家收集整理的这篇文章主要介绍了swift泛型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

简单的

// 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

猜你在找的Swift相关文章