利用泛型作为参数的函数叫做泛型函数

/*

 泛型: 在此以前我们介绍数组和可选型的时候, 大家已接触到泛型,
泛型代码能够确认保证写出灵活的, 可选拔的函数

 */

 

/// 在Swift中, 有参数的函数必须钦定参数的花色,
现在有多少个同名的函数达成相似的效率, 不过参数的类别不一致, 举例:

/*

func show(para:Int) {

    print(“Hello \(para)”)

}

func show(para:String) {

    print(“Hello \(para)”)

}

func show(para:Double) {

    print(“Hello \(para)”)

}

*/

 

//1.尽管系统能够依据参数类型调用分化的参数, 但在概念上这种艺术太过冗余.
泛型所推动的利润便是可以经过定义单个函数来促成地点的成效.
使用泛型作为参数的函数叫做泛型函数, 上面是与上例有同一的泛型函数定义:

 

func show<T>(para:T) {

    print(“Hello \(para)”)

}

show(para: “小韩哥”) // 输出”Hello 小韩哥”

show(para: 12) //输出 “Hello 12”

 

 

//2.泛型函数在注解时选取了节点类型命名(平日情状下用字母 T, U, V
那样的大写字母来表示)来代表实际类型名(如: Int, String 或 Double).
节点类型在概念时不意味着其他现实品种,
在函数被调用时会依照传入的实际类型来制定本身的类型. 其余索要提出的是,
假若函数的泛型列表唯有叁个 T, 纵然具体品种没有要求钦定,
可是种种节点类型的参数必须是同样类别的. 譬如:

func show1<T>(para:T,para2:T){}

//在调用那一个函数时, 多个参数必须是同等的品种:

show1(para: 1, para2: 2)

show1(para: “小花”, para2: “小明”)

 

 

//3.概念八个不等门类的泛型,则必要在街括号中进入八个节点:<T,U,V> ;

 

//你能够对节点开展部分限制, 比如供给泛类型坚守有些协议,
Swift中数组的判等就是这么定义的:

//public func ==<Element : Equatable>(lhs: [Element], rhs:
[Element]) ->Bool

 

//Element 是节点注明的, 它代表贰个泛型, 能够看到此间的泛型名是Element,
相比较下边包车型客车”T”,”U”,”V”长的多. 那是因为这边的
Element不独有是二个占位符的功能, 它还扬言了那么些泛型代表数组中的成分类型,
有实际的意义, 这种 API 的准备指的大家借鉴;

 

//4.一时候节点中的泛型必要有更加多的限量, 须求运用 where
子句来补充约束规范:

/*

func anyCommonElements<T : SquenceType, U : SequenceType>(lhs : T,
_ rhs : U) -> Bool where

    T.Generator.Element: Equatable,

    T.Generator.Element == U.Generator.Element{

    return false

}

 */

 

 

 

/*

 泛型协议

 */

// 这里的Element不仅彰显泛型的优势,
还隐性的牢笼了三个主意的参数必须是一律类其余.

protocol SomeProtocol {

    associatedtype Element

    func elementMethod1(element: Element)

    func elementMethod2(element: Element)

}

 

struct TestStruct:SomeProtocol {

    func elementMethod1(element: String) {

        print(“elementMethod1: \(element)”)

    }

    func elementMethod2(element: String) {

        print(“elementMethod2: \(element)”)

    }

}

 

利用泛型作为参数的函数叫做泛型函数。// 类似于associatedtype的还有 self 关键字, 代表了研究遵循着自己的种类,
适用于比较那类方法, 其必须传入另八个一律档案的次序的参数才有意义:

protocol CanCompare {

利用泛型作为参数的函数叫做泛型函数。    func isBigger(other:Self) -> Bool

利用泛型作为参数的函数叫做泛型函数。}

 

struct BoxInt:CanCompare {

    var intValue:Int

    func isBigger(other: BoxInt) -> Bool {

        return self.intValue > other.intValue

    }

}

print(BoxInt(intValue: 3).isBigger(other: BoxInt(intValue: 2))) //true

 

 

/*

 泛型对象:

 */

struct TestStruct2< T: Comparable > {

    func elementMethod3(element:T){

        print(“elementMethod3:\(element)”)

    }

    

    func elemetMethod4(element:T){

        print(“elementMethod4:\(element)”)

    }

}

let test = TestStruct2<Int>()

test.elementMethod3(element: 1) //elementMethod3:1

 

//注意:假若你品尝在落实时”嵌套”八个泛型,那么会工巧泛型不恐怕被特化;
比方数组本人是泛型的,在宣称数组类型时传入了另四个泛型,
那么您将不只怕开始化该数组:

利用泛型作为参数的函数叫做泛型函数。struct TestStruct3< T:Comparable >{

    

    var array:[T] = [1,3,4,5] as! [T] // as! [T] 
这样一般就能够一挥而就了, 不过这么泛型就不曾意思了

    

}

 

/*

 泛型方法: 方法中的泛型使用节点表示法,
使用域只在本方法内,接上头案例修改:

 */

利用泛型作为参数的函数叫做泛型函数。struct TestStruct4 {

    func elementMethod1< T: Comparable >(element:T){

        print(“===elementMethod3:\(element)”)

    }

    

    func elemetMethod2< T: Comparable >(element:T){

        print(“===elementMethod4:\(element)”)

    }

}

let test2 = TestStruct4()

test2.elementMethod1(element: 1)

test2.elemetMethod2(element: “abc”)

 

 

/*

 协议中的 where 关键字:`

 在前头我们已接触到 where关键字, where 能够和 for in 循环合营实现筛选,
where同样可以在协议扩充中;

 */

protocol SomeProtocol2 {

    associatedtype OwnElement

    func elementMethod1(element:OwnElement)

    func elementMethod2(element:OwnElement)

}

extension SomeProtocol2 where Self:Collection {

    func showCount(){

        print(self.count)

    }

}

extension Array:SomeProtocol2{

 

    func elementMethod1(element: String) {

        print(“elementMethod1:\(element)”)

    }

    func elementMethod2(element: String) {

        print(“elementMethod2:\(element)”)

    }

}

[1,2,3].showCount() //3

 

 

/*

 泛型特化: LLVM 编写翻译将 C 和 OC 的代码放在二个低档的容器中,
然后编写翻译成机器代码; 运营泛型并非很安全;

 */

 

//知识点补充:

//输出常量和变量,
能够用print(_:separator:terminator:)函数来输出当前常量或变量的值:

//print(_:separator:terminator:)是八个用来输出二个或四个值到适合输出区的全局函数。倘诺用
Xcode,print(_:separator:terminator:)将会输出内容到“console”面板上。separator和terminator参数具备暗中认可值,因而调用那几个函数的时候能够忽略它们。暗中认可情形下,该函数通过丰盛换行符来截至最近行。假如不想换行,能够传递叁个空字符串给terminator参数–比如,print(someValue,
terminator:””)。

 

func and<T>(first:T,_ second:T) {

    print(first,second, separator: “+”, terminator: “”)

}

and(first: 3, 5)

and(first: “a”, “b”)

 

// 此时 LLVM 在编写翻译时会把 and 函数特化为:

func and(first:Int,_ second:Int){

    print(first,second, separator: “+”, terminator: “”)

}

//以及

func and(first:String,_ second:String){

    print(first,second, separator: “+”, terminator: “”)

}

 

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图