美文网首页
Swift泛型初探

Swift泛型初探

作者: 蔡俊宇 | 来源:发表于2016-09-29 22:53 被阅读45次

其实真的觉得即使自己能独立完成项目,还有是太多太多学习的地方可以不断提高,毕竟如果重复写一些代码是没有意义的.虽然说我已经使用了swift写了一个项目并且已经在AppStore里面发布,但是对于swift的认识还是很浅薄的.最近在重新看swift programming language一书,重新看了一遍里面的内容--其实对于泛型,我最初的理解是来源于Java,在项目中我真的比较少用到泛型.

泛型需求的产生

下面是书里面的代码:

  func swapTwoInt(inout a:Int,inout b:Int){
    let tempA = a;
    a = b;
    b = tempA
}

要是我有这个交换两个内容的要求,但是这紧紧单纯是对Int但种类型的配置,如果我还需要有String和Double的话,我必须要拷贝代码:

func swapTwoString(inout a:String,inout b:String){
      let tempA = a;
      a = b;
      b = tempA
}

  func swapTwoDouble(inout a:Double,inout b:Double){
      let tempA = a;
      a = b;
      b = tempA
 }

于是我们产生了泛型,它可以定义一种统一的类型<T>,这个时候你可以在参数里面写入这个参数,它代表了前后一致的类型,如String,Int,Double...

func swapTwoValues<T>(inout a: T, inout _ b: T){
   let tempA = a;
   a = b;
   b = tempA
 }

在我写泛型的时候,遇到的第一个问题是返回值怎么处理?
唔哼,这个问题让我们继续把泛型的其他定义看下去的时候再继续思考吧.

命名类型参数

那么,泛型的书写方法就是用一对箭括号把类型名称合并起来:如 <T>,当然,你也可以一两个其他字母表示,<U,T>

泛型类型

其中,书中里面举了一个泛型类型的例子是这样的:

struct IntStack {
var items = [Int]();
/*
 mutating关键字:由于swift功能强大,不仅可以让class遵守,也可以让enum和struct遵守
 mutating关键字在定义协议的方法的时候可以在前面加上,让其三种类型在遵守协议的时候对有关键字的方法有不同的"提示":
class: 在class中实现带有mutating方法的接口时,不用mutating进行修饰。因为对于class来说,类的成员变量和方法都是透明的,所以不必使用 mutating 来进行修饰
 enum:
 struct:如果将struct中的mutating去掉,则会报错不能改变结构体的成员。
*/
//将一个数值入栈
mutating func push(item:Int)
{
    items.append(item)
    
}

//和内存中的栈一样,先进后出,所以只要移除最后一个元素即可
mutating func pop() -> Int{
    
    return items.removeLast()
  }

}

但是只针对Int一种类型避免也显得太弱了吧,所以我们可以用泛型对其进行改良:

struct Stack<T> {
  var items = [T]()
  mutating func push(item: T) {
    items.append(item)
  }
  mutating func pop() -> T {
    return items.removeLast()
  } 
}

使用的时候可以将该类型延伸为相应的类型,如string:

var stringsInStack = Stack<String>()
stringsInStack.push("1");//1
stringsInStack.push("2");//1,2
stringsInStack.push("3");//1,2,3
stringsInStack.push("4");//1,2,3,4
stringsInStack.pop()//1,2,3

现在,有点明白了Array和Dictionary为什么可以指定类型了吧,其实无形中我们已经用了很多泛型的内容,只是我们缺少了总结和理解:

 //定义了一个内容必须为字符串的数组
 var arr :[String] = []
 arr[0] = "name";
 arr[1] = "age";
 arr[3] = "height";

//定义了一个key为String,value为AnyObject的字典  
  var parma : [String:AnyObject] = [:]
  parma["name"] = "shiron"
  parma["age"] = 22
  parma["height"] = 1.70

这里可以延伸出后面的一个话题:类型约束.

类型约束

输入Dictionary点进去可以看到该类的属性和方法:

public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible{
各种dict的属性和方法......
}

我们发现在dict对泛型进行定义的时候,key有一个特殊的限制:

****<key: hashable,Value>****
此时,我们可以看到key被强制遵守了一个hashable的协议(注意:Swift 标准库中定义的一个特定协议,所有的 Swift 基本类型(如 String , Int , Double 和 Bool )默认都是可哈希。)

当你对泛型的有较高的输入要求时,可以限制某种类或者协议来进行类型约束,定义方法就是在泛型字母后面添加 T:SomeProtocol或者U:someClass

func someFunction<T:someClass,U:someProtocol>(someT:T,someU:U){
//函数主体
}

扩展一个泛型类型

当然我们泛型的好用之处不仅这么一点点.

书中还对Stack的类型作出了一个扩展:

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

topItem 属性会返回一个 T 类型的可选值。当栈为空的时候, topItem 将会返回 nil ;当栈不为空的时候, topItem 会返回 items 数组中的最后一个元素,然而你注意到了吗?我们在扩展里面并没有使用泛型类型的定义,它是从结构体中直接带过来了,对它进行解包则可以自己使用:

 if let topItem = stackOfStrings.topItem { 
    print(" \(topItem)")
}

相关文章

  • Swift泛型初探

    其实真的觉得即使自己能独立完成项目,还有是太多太多学习的地方可以不断提高,毕竟如果重复写一些代码是没有意义的.虽然...

  • 唬人的Java泛型并不难

    泛型 上面的代码有什么区别? 泛型初探 1、为何引入泛型? Java 泛型也是一种语法糖,使用泛型可以在代码编译阶...

  • Swift-泛型笔记

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

  • [ WWDC2018 ] - Swift 泛型 Swift Ge

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

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

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

  • 2021-12-01

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

  • swift 泛型

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

  • 使用Web浏览器编译Swift代码,及Swift中的泛型

    使用Web浏览器编译Swift代码,及Swift中的泛型 使用Web浏览器编译Swift代码,及Swift中的泛型

  • 【Swift】泛型常见使用

    1、Swift泛型4种 泛型函数泛型类型泛型协议泛型约束 2、泛型约束3种 继承约束:泛型类型 必须 是某个类的子...

  • OneDayOneSwift[23] - Generics

    泛型是 Swift 的强大特性之一,许多 Swift 标准库是通过泛型代码构建的。事实上,泛型的使用贯穿了整本语言...

网友评论

      本文标题:Swift泛型初探

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