- 泛型可以将类型参数化,提高代码服用率,减少代码
func swapValues<T>(_ a: inout T,_ b: inout T) {
(a,b) = (b,a)
}
var i1 = 10
var i2 = 20
print(i1)
print(i2)
swap(&i1, &i2)
print(i1)
print(i2)
struct Date {
var year = 0,month = 0,day = 0
}
var dd1 = Date(year: 2011, month: 2, day: 3)
var dd2 = Date(year: 2012, month: 10, day: 12)
print(dd1)
print(dd2)
swapValues(&dd1, &dd2)
print(dd1)
print(dd2)
//打印结果
10
20
20
10
Date(year: 2011, month: 2, day: 3)
Date(year: 2012, month: 10, day: 12)
Date(year: 2012, month: 10, day: 12)
Date(year: 2011, month: 2, day: 3)
- 类实现栈结构
class Stack<E> {
var elements = [E]()
func push(_ element: E) {
elements.append(element)
}
func pop() -> E {
return elements.removeLast()
}
func top() -> E {
return elements.last!
}
func size() -> Int {
return elements.count
}
}
var stack = Stack<Int>()
stack.push(11)
stack.push(22)
stack.push(33)
print(stack.top())//33
print(stack.pop())//33
print(stack.pop())//22
print(stack.size())//1
class SubStack<E> : Stack<E> {
}
- 结构体实现栈结构
struct Stack<E> {
var elements = [E]()
mutating func push(_ element: E) {
elements.append(element)
}
mutating func pop(_ element: E) {
elements.removeLast()
}
func top() -> E {
return elements.last!
}
func size() -> Int {
return elements.count
}
}
结构体关联值使用泛型
enum Score<T> {
case point(T)
case grade(String)
}
let score0 = Score<Int>.point(100)
let score1 = Score.point(99)
let score2 = Score.point(90.2)
let score3 = Score<String>.grade("A")
关联类型(Associated Type)
- 关联类型的作用: 给协议中用到的类型定义一个占位名称
- 协议中可以拥有多个关联类型
protocol Stackable {
associatedtype Element //关联类型
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}
class Stack<E>: Stackable {
typealias Element = E
var elements = [E]()
func push(_ element: Stack<E>.Element) {
elements.append(element)
}
func pop() -> Stack<E>.Element {
return elements.removeLast()
}
func top() -> Stack<E>.Element {
return elements.last!
}
func size() -> Int {
return elements.count
}
}
protocol Stackable {
associatedtype Element //关联类型
mutating func push(_ element: Element)
mutating func pop() -> Element
func top() -> Element
func size() -> Int
}
class StringStack: Stackable {
//给关联类型设定真实类型
typealias Element = String
var elements = [String]()
func push(_ element: String) {
elements.append(element)
}
func pop() -> String {
return elements.removeLast()
}
func top() -> String {
return elements.last!
}
func size() -> Int {
return elements.count
}
}
var ss = StringStack()
ss.push("Jack")
ss.push("Rose")
print(ss.pop())//Rose 不是e
类型约束
class Person {}
func swapValues<T : Person & Runnable>(_ a: inout T,_ b: inout T) {
(a,b) = (b,a)
}
protocol Stackable {
associatedtype Element: Equatable
}
class Stack<E : Equatable>: Stackable {
//typealias Element = <#type#>
}
func equal<S1: Stackable,S2: Stackable>(_ s1: S1,_ s2: S2) -> Bool
where S1.Element == S2.Element,S1.Element : Hashable{
return false
}
var stact1 = Stack<Int>()
var stack2 = Stack<String>()
equal(stact1, stack2)
协议作为返回值类型
protocol Runnable { }
class Person: Runnable {}
class Car: Runnable { }
func get(_ type: Int) -> Runnable {
if type == 0 {
return Person()
}
return Car()
}
var r1 = get(0)
var r2 = get(1)
protocol Runnable {
associatedtype Speed
var speed: Speed { get }
}
class Person: Runnable {
var speed: Double { return 0.0 }
}
class Car: Runnable {
var speed: Int { return 0 }
}
- 如果协议中有
associatedtype或者使用了Self作参数会报错
image.png
- 方案一: 使用泛型
protocol Runnable {
associatedtype Speed
var speed: Speed { get }
}
class Person: Runnable {
var speed: Double { return 0.0 }
}
class Car: Runnable {
var speed: Int { return 0 }
}
func get<T : Runnable>(_ type: Int) -> T {
if type == 0 {
return Person() as! T
}
return Car() as! T
}
var r1: Person = get(0)
var r2: Car = get(1)
- 方案2: 使用
some关键字(Opaque Type, 不透明类型)
protocol Runnable {
// associatedtype Speed
// var speed: Speed { get }
}
class Person: Runnable {
// var speed: Double { return 0.0 }
}
class Car: Runnable {
//var speed: Int { return 0 }
}
func get(_ type: Int) -> some Runnable {
Car()
}
-
some限制只能返回一种类型.下面代码报错
protocol Runnable {
// associatedtype Speed
// var speed: Speed { get }
}
class Person: Runnable {
// var speed: Double { return 0.0 }
}
class Car: Runnable {
//var speed: Int { return 0 }
}
func get(_ type: Int) -> some Runnable {
if type == 0 {
return Person()
}
return Car()
}
可选项的本质
- 可选项的本质是
enum类型
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
public init(_ some: Wrapped)
}
var age: Int? = .none
age = 10
age = .some(20)
age = nil
var age: Int? = 10
var age0: Optional<Int> = Optional<Int>.some(10)
var age1: Optional = .some(10)
var age2 = Optional.some(10)
var age3 = Optional(10)
age = nil
age3 = .none
var age: Int? = nil
var age0 = Optional<Int>.none
var age1: Optional<Int> = .none
var age: Int? = nil
var age0 = Optional<Int>.none
var age1: Optional<Int> = .none
switch age {
case let v?:
print("some",v)
case nil:
print("none")
}
switch age {
case let .some(v):
print("some",v)
case .none:
print("none")
}
var age_: Int? = 10
var age: Int?? = age_
age_ = nil
var age0 = Optional.some(Optional.some(10))
age0 = .none
var age1: Optional<Optional> = .some(.some(10))
var age: Int?? = 10
var age0: Optional<Optional> = 10








网友评论