Swift学习泛型

作者: 冷武橘 | 来源:发表于2020-10-15 11:37 被阅读0次
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)

swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两个 Double 值,你只能再写更多的函数。

一、函数

为了解决类似上面的问题,我们可以用一个泛型函数去表示一个函数

func swapTwo<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwo(&someInt, &anotherInt)

var someString = “3”
var anotherString = “17”
swap(&someString, &anotherString)
  • 占位符类型 T 就是一个类型形式参数指定并且命名一个占位符类型,紧挨着写在函数名后面的一对尖括号里(比如 <T> )。
  • 大多数情况下,类型形式参数的名字要有描述性,比如 Dictionary<Key, Value> 中的 Key 和 Value ,借此告知读者类型形式参数和泛型类型、泛型用到的函数之间的关系。但是,他们之间的关系没有意义时,一般按惯例用单个字母命名,比如 T 、 U 、 V ,比如上面的 swapTwoValues(::) 函数中的 T 。

1.2、泛型函数赋给变量

func test<T1,T2>(t1:T1,t2:T2){
    print(t1,t2)
}

var fn:(Int,Int)->() = test
var fn1:(Int,String)->() = test
var fn2:(String,String)->() = test
fn(10,20)
fn1(10,"你好")
fn2("大家好","你好")

二、类型

除了泛型函数,Swift允许你定义自己的泛型类型。它们是可以用于任意类型的自定义类、结构体、枚举,和 Array 、 Dictionary 方式类似。

class Stack<Element>{
    var items = [Element]()
     func push(_ item: Element) {
         items.append(item)
     }
   func pop() -> Element {
         return items.removeLast()
     }
}
class Stack<Element>{
    var items = [Element]()
     func push(_ item: Element) {
         items.append(item)
     }
   func pop() -> Element {
         return items.removeLast()
     }
}

var stack = Stack<String>()
stack.push(“ssss”)

var stack1 = Stack<Int>()
stack1.push(10)
  • 这个泛型的 Stack 和非泛型版本的本质上是一样的,只是用一个叫做 Element 的类型形式参数代替了实际的 Int 类型。这个类型形式参数写在一对尖括号( <Element> )里,紧跟在结构体名字后面。Element 为稍后提供的”某类型 Element “定义了一个占位符名称。这个未来的类型可以在结构体定义内部任何位置以” Element “引用。在这个例子中,有三个地方将 Element 作为一个占位符使用:
struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
stackOfStrings = Stack<String>()
stackOfStrings.push(“uno”)
stackOfStrings.push(“dos”)
stackOfStrings.push(“tres”)
stackOfStrings.push(“cuatro”)
enum Socre<T> {
   case point(T)
   case grade(String)
}

let score0 = Socre<Int>.grade("")
let score1 = Socre.point(3)
let score2 = Socre<Int>.point(100)

三、关联类型

在泛型函数中,你可以在函数名后面紧跟着一个类型形式参数,来表明泛型。然在协议中你不能这样去表示,编译器是不允许的。你需要在内部声明一个关联类型来表示泛型。

protocol Test {
    associatedtype Element
    mutating func append(_ item: Element)
       var count: Int { get }
       subscript(i: Int) -> Element { get }
}
  • 用associatedtype关键字可以声明一个关联类型
  • 关联类型作用:在协议中声明一个泛型类
class Student: Test {
    typealias Element = String// 给关联类型设定真实类型
    func append(_ item: String) {}
    var count: Int = 0
    subscript(i: Int) -> String {
         return “333”
    }
}
class Person: Test {
    typealias Element = Int// 给关联类型设定真实类型
    func append(_ item: Int) {}
    var count: Int = 0
    subscript(i: Int) -> Int {
         return 333
    }
}

四、类型约束

protocol Runnable{}
class Person{}
func swapValues<T:Person&Runnable>(a:T,b:T){}
protocol Stackable {
    associatedtype Eleement:Equatable
} 
class Stack<E:Equatable>:Stackable{
    typealias Eleement = E
}

var stack = Stack<Int>()

五、不透明类型

如果协议中有 associatedtype,


截屏2020-01-14下午5.12.29.png
解决方案1:使用泛型
func test<T:Runnable>(a:Int) ->  T{
    return Person() as! T
}
解决方案2:不透明类型

使用some关键字声明一个不透明类型

func test(a:Int) ->  some Runnable{
    return Person()
}

相关文章

  • swift 泛型

    Swift-泛型学习和实例总结 - Mazy's Blog - CSDN博客 Swift中的泛型 - 简书

  • Swift-泛型笔记

    Swift 泛型 Swift 提供了泛型让你写出灵活且可重用的函数和类型。 Swift 标准库是通过泛型代码构建出...

  • [ WWDC2018 ] - Swift 泛型 Swift Ge

    Swift 泛型历史 我们首先来回顾一下 Swift 中对于泛型支持的历史变更,看看现在在 Swift 中,泛型都...

  • Swift 运用协议泛型封装网络层

    Swift 运用协议泛型封装网络层 Swift 运用协议泛型封装网络层

  • 2021-12-01

    swift5基本语法-泛型函数和泛型类型 Swift中泛型可以将类型参数化,提高代码复用率,减少代码量。 一、泛型...

  • Swift学习:泛型

    本篇将详细总结介绍Swift泛型的用法;Swift泛型代码让你能够根据自定义的需求,编写出适用于任意类型、灵活可重...

  • Swift学习_泛型

    泛型泛型的本质是参数化类型,也就是说所有操作的数据类型被制定为一个参数,这种参数类型可以用在类型、函数和方法中。 ...

  • Swift学习:泛型

    使用泛型的原因: 例如: 但是,如果传值的时候需要考虑的问题很多,也影响性能(例子存在问题) 因此需要这样设置泛型...

  • Swift学习泛型

    swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两...

  • Swift泛型

    泛型是 Swift 最强大的特性之一,oc转Swift的需要重点学习一下。① 泛型代码能根据所定义的要求写出可以用...

网友评论

    本文标题:Swift学习泛型

    本文链接:https://www.haomeiwen.com/subject/jeenpktx.html