• Swift学习-Generics


    1.泛型:

    用于编写灵活且可重用的代码,这些代码可以跨多种类型工作。因此,我们可以设置泛型类型,而不是为Int、String等每个类型创建不同的函数/结构。泛型类型也称为占位符类型。
    要创建泛型函数,需要在尖括号中的函数名后面设置一个占位符值:
    通常,如果泛型参数占位符不表示任何内容,请使用T、U、V等。
    下面是示例:

    func printMe<T>(a: T)
    {
        print(a)
    }
    printMe(a: 1)
    printMe(a: "Anupam")
    //交换两个数据的值
    func swapAandB<T>(_ a: inout T, _ b: inout T) {
        let temporaryA = a
        a = b
        b = temporaryA
    }
    var x = "hello"
    var y = "world"
    
    swapAandB(&x, &y)
    print(x)
    print(y)
    
    var x1 = 2
    var y1 = 3
    swapAandB(&x1, &y1)
    print(x1)
    print(y1)
    
    

    泛型只能是同一类型的,不同类型会报错
    我们可以通过使用两个泛型参数来处理上述规则。我们必须在函数头本身中声明它们:

    func printTandU<T,U>(a:T,b:U){
        print("T is (a) and U is (b)")
    }
    
    printTandU(a:1,b:"Swift Generics")
    

    2.泛型约束

    我们还可以约束泛型类型以符合某个类型。

    class Person{
        var name:String?
        var age:Int
        init(name:String,age:Int){
            self.name = name
            self.age = age
        }
    }
    func printDetails<T:Person>(a:T,b:T){
        print("a is (a.name ?? "NA") and age (a.age)")
        print("b is (b.name ?? "NA") and age (b.age)")
    }
    var p1 = Person(name:"Harry Potter",age:11)
    var p2 = Person(name:"Dumbledore",age:700)
    
    printDetails(a:p1,b:p2)
    

    T符合Person的类型。因此,不能传递任何不属于上述代码中Person类型的值。
    子类将符合泛型参数类型。

    泛型类型必须符合协议的另一个示例:

    func compareAandB<T:Equatable>(a:T,b:T){
        print("a == b ? (a==b)")
    }
    
    compareAandB(a:2,b:3)
    compareAandB(a:"Hi",b:"Hi")
    

    ==将不起作用,当没有Equatable协议时

    3.对泛型类型使用扩展

    struct Stack<T>{
        var items = [T]()
        mutating func push(_ item : T){
            items.append(item)
        }
        mutating func pop() -> T {
            return items.removeLast()
        }
    }
    
    var stackOfInt = Stack<Int>()
    stackOfInt.push(2)
    stackOfInt.push(3)
    print(stackOfInt.items)//打印结果:[2,3]
    
    var stackOfString = Stack<String>()
    stackOfString.push("Hello")
    stackOfString.push("World")
    print(stackOfString.items)//打印结果:["Hello", "World"]
    

    我们不必再次在扩展中设置泛型类型。

    extension Stack{
        var top : T?{
            return items.isEmpty ? nil : items[items.count - 1]
        }
    }
    

    4.使用where子句进行泛型类型检查

    我们可以使用where子句进行更严格的泛型类型约束检查。在where子句中我们可以添加附加条件。

    protocol Hogwarts{}
    protocol Muggles {}
    
    class People  : Hogwarts{
        var name : String?
        var age : Int
        init(name:String,age:Int){
            self.name = name
            self.age = age
        }
    }
    
    class M : People,Muggles{}
    
    func printDetailsTemp<T:People>(a:T) where T:Muggles{
        print("a is (a.name ?? "NA") and age (a.age)")
    }
    
    var person1 = People(name:"Harry Potter",age:11)
    var m2 = M(name:"Hermione",age:700)
    var person3 = People(name:"Ron",age:11)
    
    printDetailsTemp(a : m2)//打印结果:a is Hermione and age 700
    
    printDetailsTemp(a : person1)//编译错误:global function 'printDetailsTemp(a:)' requires that 'People' conform to 'Muggles'
    

    因此,在上面的代码中,我们添加了一个checker,其中类型T除了符合类People之外,还必须符合Muggles协议。所以,在上面的代码中,它只接受类M的类型。而不是People这个类型

  • 相关阅读:
    python函数练习题2
    python函数练习题1
    数字是否是10的整数倍
    关于循环的作业:登陆程序
    用for循环写这段代码
    while循环语句
    在CentOS8 上安装Python3
    时隔半年再写购物车程序并改进
    vue上传
    根据生日计算年龄
  • 原文地址:https://www.cnblogs.com/PotatoToEgg/p/15039981.html
Copyright © 2020-2023  润新知